Codeforces Round #526 (Div. 2) Solution

Posted dup4

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #526 (Div. 2) Solution相关的知识,希望对你有一定的参考价值。

A. The Fair Nut and Elevator

Solved.

签.

技术分享图片
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 #define N 110
 5 int n, a[N];
 6 
 7 int main()
 8 {
 9     while (scanf("%d", &n) != EOF)
10     {
11         for (int i = 1; i <= n; ++i) scanf("%d", a + i);
12         int res = 1e9;
13         for (int x = 1, tmp = 0; x <= 100; ++x, res = min(res, tmp), tmp = 0) for (int i = 1; i <= n; ++i) if (a[i])
14         {
15             tmp += a[i] * (abs(x - i) + abs(i - 1) + abs(x - 1) + abs(x - 1) + abs(i - 1) + abs(x - i)); 
16         }
17         printf("%d
", res);
18     }
19     return 0;
20 }
View Code

 

B. Kvass and the Fair Nut

Upsolved.

题意:

刚开始题意读错,过了pretest就没管了

有$n桶啤酒,要从中取出s升,求取出后剩余的量最少的那桶啤酒最大$

思路:

二分或者直接算都行

技术分享图片
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 #define ll long long
 5 #define N 1010
 6 int n;
 7 ll s, v[N];
 8 
 9 bool check(ll x)
10 {
11     ll tot = 0;
12     for (int i = 1; i <= n; ++i) 
13     {
14         if (v[i] < x) return false;  
15         tot += v[i] - x;
16     }
17     return tot >= s;
18 }
19 
20 int main()
21 {
22     while (scanf("%d%lld", &n, &s) != EOF)
23     {
24         for (int i = 1; i <= n; ++i) scanf("%lld", v + i);
25         ll l = 0, r = 1e9, res = -1; 
26         while (l <= r)
27         {
28             ll mid = (l + r) >> 1;
29             if (check(mid))
30             {
31                 res = mid;
32                 l = mid + 1;
33             }
34             else
35                 r = mid - 1;
36         }
37         printf("%lld
", res);
38     }
39     return 0;
40 }
View Code

 

C. The Fair Nut and String

Solved.

题意:

有一串字符串,求有多少个字符串,是abababab形式的。

思路:

字符不是‘a’ 也不是‘b’ 的话是没用的,然后如果两个‘a‘之间有多个‘b‘也没用

缩短字符串后

必然是aaabaaababab  这样的形式的

那么像统计DAG那样统计就没了

技术分享图片
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 #define ll long long
 5 #define N 100010
 6 const ll MOD = (ll)1e9 + 7;
 7 char s[N], t[N];
 8 
 9 int main()
10 {
11     while (scanf("%s", s + 1) != EOF)
12     {
13         int n = 0; 
14         for (int i = 1, len = strlen(s + 1); i <= len; ++i) if (s[i] == a || s[i] == b)
15         {
16             if (s[i] == a) t[++n] = a;  
17             else if (s[i] == b && t[n] == a) t[++n] = b;  
18         }
19         if (n == 0)
20         {
21             puts("0");
22             continue;
23         }
24         ll res = 1, pre = 1, cnt = 1; 
25         for (int i = 2; i <= n; ++i)  
26         {
27             if (t[i] == b) 
28             {
29                 pre = (pre * (cnt + 1)) % MOD;
30                 cnt = 0; 
31             }    
32             else 
33             {
34                 ++cnt;
35                 res = (res + pre) % MOD;
36             }
37         }
38         printf("%lld
", res);
39     }
40     return 0;
41 }
View Code

 

D. The Fair Nut and the Best Path

Upsolved.

题意:

在一棵树上,每个点是加油站,最多加油$w_i,然后每条边是路,耗费油v_i$

$定义f(u, v)为u->v的简单路径上每个点都加满油,假设油箱容量无限,最后剩下的油量$

如果其中某条路上油耗尽了,那么这条路是不可行的

思路:

我们把点权视为正直,边权视为负值

然后就是求任意两点之间的最大权值和

不需要考虑不合法的路径,因为如果存在不合法的路劲,

那么肯定存在另一条合法的路径使得答案比它更优。

令$f[u] 表示到达u的子树中某点的最大权, 这是纵向路径$

再考虑横向路径即可

技术分享图片
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 #define ll long long
 5 #define N 300010
 6 #define pii pair <int, int>
 7 int n, w[N];
 8 vector <pii> G[N];
 9 ll res, f[N];
10 
11 void DFS(int u, int fa)
12 {
13     f[u] = w[u];
14     ll Max[2] = {0, 0};
15     for (auto it : G[u]) 
16     {
17         int v = it.first; 
18         if (v == fa) continue;
19         DFS(v, u);
20         ll cost = it.second;
21         f[u] = max(f[u], f[v] - cost + w[u]);
22         ll tmp = f[v] - cost;
23         if (tmp > Max[0])
24         {
25             Max[1] = Max[0];
26             Max[0] = tmp;
27         }
28         else if (tmp > Max[1])
29             Max[1] = tmp;
30     }
31     res = max(res, max(f[u], Max[0] + Max[1] + w[u])); 
32 }
33 
34 int main()
35 {
36     while (scanf("%d", &n) != EOF)
37     {
38         for (int i = 1; i <= n; ++i) scanf("%d", w + i);
39         for (int i = 1; i <= n; ++i) G[i].clear();
40         for (int i = 1, u, v, w; i < n; ++i)
41         {
42             scanf("%d%d%d", &u, &v, &w);
43             G[u].emplace_back(v, w);
44             G[v].emplace_back(u, w);
45         }
46         res = 0;
47         DFS(1, 1);
48         printf("%lld
", res);
49     }    
50     return 0;
51 }
View Code

 

E. The Fair Nut and Strings

Unsolved.

题意:

一共有k个长度为n的字符串,他们的范围是[s, t] 之间,按字典序排序

求这些字符串最多有多少个前缀

 

F. Max Mex

Unsolved.

 

以上是关于Codeforces Round #526 (Div. 2) Solution的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces Round #526 (Div. 2) E. The Fair Nut and Strings

Codeforces Round #526 (Div. 2) C. The Fair Nut and String

Codeforces Round #526 (Div. 2) D. The Fair Nut and the Best Path

Codeforces Round #526 C - The Fair Nut and String /// 组合递推

CF1083(Round #526 Div. 1) 简要题解

Codeforces Round #436 E. Fire(背包dp+输出路径)