• 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
    ");
    19     else if (x == n && odd % 2 == 0)
    20         printf("No
    ");
    21     else if (!even && x % 2 == 0)
    22         printf("No
    ");
    23     else
    24         printf("Yes
    ");
    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
    ", 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
    ");
    19         return;
    20     }
    21     printf("%s", n % 2 ? "Ashish
    " : "Ayush
    ");
    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, " 
    "[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, " 
    "[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], " 
    "[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, " 
    "[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$三个值,分别代表这个点的代价,这个点的初始颜色,这个点的目标颜色,颜色只有黑和白。对于每个点,我们可以在以它为根的子树中任意选择一些点,将它们的颜色任意分配,代价是这个点代价$ imes$点数。求把整棵树变成目标颜色的最小代价,或者输出$-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
    "), 0;
    48     dfs(1, 0, a[1]);
    49     printf("%lld
    ", ans);
    50     return 0;
    51 }
    View Code
  • 相关阅读:
    78. Subsets
    [LintCode] 447 Search in a Big Sorted Array
    [LintCode] 585 Maximum Number in Mountain Sequence
    [LintCode] Search a 2D Matrix
    [LintCode] 459 Closest Number in Sorted Array
    [z]Google SPDY介绍
    Python Snippet
    python学习[二]
    [转]总结的几大驭下法宝
    python学习[一]
  • 原文地址:https://www.cnblogs.com/Aya-Uchida/p/13110930.html
Copyright © 2020-2023  润新知