codeforces Round 646(div. 2)


A、Odd Selection

题意:

$n$个数选$x$个数能不能使它们的和是奇数。

题解:

按奇偶分一波情况就行。

AC代码:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int N = 1e5 + 5;
 5 void solve()
 6 {
 7     int n, x, a;
 8     scanf("%d%d", &n, &x);
 9     int odd = 0;
10     for (int i = 1; i <= n; ++i)
11     {
12         scanf("%d", &a);
13         if (a % 2)
14             ++odd;
15     }
16     int even = n - odd;
17     if (!odd)
18         printf("No\n");
19     else if (x == n && odd % 2 == 0)
20         printf("No\n");
21     else if (!even && x % 2 == 0)
22         printf("No\n");
23     else
24         printf("Yes\n");
25 }
26 int main()
27 {
28     int T;
29     scanf("%d", &T);
30     while (T--)
31         solve();
32     return 0;
33 }
View Code

B、Subsequence Hate

题意:

改变最少的位置使得$01$串没有$010$和$101$子序列

题解:

只有$4$可能,处理前缀和然后枚举位置

AC代码:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int N = 1e3 + 5;
 4 char s[N];
 5 int pre[N];
 6 void solve()
 7 {
 8     scanf("%s", s + 1);
 9     int n = strlen(s + 1);
10     for (int i = 1; i <= n; ++i)
11         pre[i] = pre[i - 1] + s[i] - '0';
12     int ans = N;
13     for (int i = 0; i <= n; ++i)
14     {
15         ans = min(ans, i - pre[i] + pre[n] - pre[i]);
16         ans = min(ans, pre[i] + n - i - (pre[n] - pre[i]));
17     }
18     printf("%d\n", ans);
19 }
20 int main()
21 {
22     int T;
23     scanf("%d", &T);
24     while (T--)
25         solve();
26     return 0;
27 }
View Code

C、Game On Leaves

题意:

无根树,每次只能删叶子,先删$x$的胜,问最优策略下谁胜

题解:

考虑最终决定胜负时只会剩下$2$个结点,所以就可以考虑谁会到这个状态

AC代码:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int N = 1e5 + 5;
 4 int deg[N];
 5 void solve()
 6 {
 7     int n, x;
 8     scanf("%d%d", &n, &x);
 9     memset(deg, 0, sizeof(deg[0]) * (n + 1));
10     for (int i = 1; i < n; ++i)
11     {
12         int u, v;
13         scanf("%d%d", &u, &v);
14         ++deg[u], ++deg[v];
15     }
16     if (deg[x] <= 1)
17     {
18         printf("Ayush\n");
19         return;
20     }
21     printf("%s", n % 2 ? "Ashish\n" : "Ayush\n");
22 }
23 int main()
24 {
25     int T;
26     scanf("%d", &T);
27     while (T--)
28         solve();
29     return 0;
30 }
View Code

D、Guess The Maximums

题意:

看不懂$QAQ$

题解:

不会$QAQ$

AC代码:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int N = 1e3 + 5;
 4 int query(int l, int r)
 5 {
 6     printf("? %d ", r - l + 1);
 7     for (int i = l; i <= r; ++i)
 8         printf("%d%c", i, " \n"[i == r]);
 9     fflush(stdout);
10     int res = 0;
11     scanf("%d", &res);
12     return res;
13 }
14 int col[N], tmp[N];
15 void solve()
16 {
17     int n, k, a, b;
18     scanf("%d%d", &n, &k);
19     memset(col, -1, sizeof(col[0]) * (n + 1));
20     for (int i = 1; i <= k; ++i)
21     {
22         scanf("%d", &a);
23         for (int j = 1; j <= a; ++j)
24         {
25             scanf("%d", &b);
26             col[b] = i;
27         }
28     }
29     int maxn = query(1, n);
30     int l = 1, r = n;
31     int maxpos = 0;
32     while (1)
33     {
34         int mid = (l + r) >> 1;
35         if (l == mid)
36         {
37             if (query(l, mid) == maxn)
38                 maxpos = l;
39             else
40                 maxpos = r;
41             break;
42         }
43         if (query(l, mid) == maxn)
44             r = mid;
45         else
46             l = mid + 1;
47     }
48     if (col[maxpos] == -1)
49     {
50         printf("! ");
51         for (int i = 1; i <= k; ++i)
52             printf("%d%c", maxn, " \n"[i == k]);
53         fflush(stdout);
54         char s[20];
55         scanf("%s", s);
56         return;
57     }
58     int top = 0;
59     for (int i = 1; i <= n; ++i)
60         if (col[i] != col[maxpos])
61             tmp[++top] = i;
62     printf("? %d ", top);
63     for (int i = 1; i <= top; ++i)
64         printf("%d%c", tmp[i], " \n"[i == top]);
65     fflush(stdout);
66     int res = 0;
67     scanf("%d", &res);
68     printf("! ");
69     for (int i = 1; i < col[maxpos]; ++i)
70         printf("%d ", maxn);
71     printf("%d ", res);
72     for (int i = col[maxpos] + 1; i <= k; ++i)
73         printf("%d%c", maxn, " \n"[i == k]);
74     fflush(stdout);
75     char s[20];
76     scanf("%s", s);
77 }
78 int main()
79 {
80     int T;
81     scanf("%d", &T);
82     while (T--)
83         solve();
84     return 0;
85 }
View Code

E、Tree Shuffling

题意:

根为$1$的树,每个点有$a,b,c$三个值,分别代表这个点的代价,这个点的初始颜色,这个点的目标颜色,颜色只有黑和白。对于每个点,我们可以在以它为根的子树中任意选择一些点,将它们的颜色任意分配,代价是这个点代价$\times$点数。求把整棵树变成目标颜色的最小代价,或者输出$-1$表示不可能。

题解:

显然更换以某个点为根的子树的点时,代价是根和它的祖先的代价的最小值。然后更新完之后回溯时要减去这棵子树中更新的。

AC代码:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int N = 2e5 + 5;
 5 vector<int> G[N];
 6 int minn[N];
 7 ll a[N], ans;
 8 int b[N], c[N];
 9 pair<ll, ll> dfs(int u, int fa, ll cost)
10 {
11     pair<ll, ll> now;
12     if (b[u] != c[u])
13     {
14         now.first += b[u];
15         now.second += c[u];
16     }
17     for (auto i : G[u])
18         if (i != fa)
19         {
20             pair<ll, ll> nxt = dfs(i, u, min(a[i], cost));
21             now.first += nxt.first;
22             now.second += nxt.second;
23         }
24     int d = min(now.first, now.second);
25     ans += 2 * d * cost;
26     now.first -= d;
27     now.second -= d;
28     return now;
29 }
30 int main()
31 {
32     int n;
33     scanf("%d", &n);
34     for (int i = 1; i <= n; ++i)
35         scanf("%lld%d%d", &a[i], &b[i], &c[i]);
36     ll sum = 0;
37     for (int i = 1; i < n; ++i)
38     {
39         int u, v;
40         scanf("%d%d", &u, &v);
41         G[u].push_back(v);
42         G[v].push_back(u);
43     }
44     for (int i = 1; i <= n; ++i)
45         sum += b[i] - c[i];
46     if (sum)
47         return printf("-1\n"), 0;
48     dfs(1, 0, a[1]);
49     printf("%lld\n", ans);
50     return 0;
51 }
View Code
posted @ 2020-06-13 14:20  Aya_Uchida  阅读(145)  评论(0编辑  收藏  举报