Codeforces Round #646 (Div. 2) D交互

A. Odd Selection

题意:

给定 n 个数,是否能选 k 个数和为奇数

分析:

和为奇数只有一种情况:n 个偶数 + k 个奇数( n 任意,k 为奇数)枚举奇数个数即可

void solve()
{
    a = b = 0;
    cin >> n >> k;
    for (int i = 1, x; i <= n; i++)
    {
        cin >> x;
        if (x & 1)
            a++;
        else
            b++;
    }
 
    bool f = false;
    for (int i = 1; i <= a; i += 2)
    {
        if (k - i <= b && k - i >= 0)
        {
            f = true;
            break;
        }
    }
    if (f)
        cout << "Yes" << endl;
    else
        cout << "No" << endl;
}

B. Subsequence Hate

题意:

给定 01 串,操作为 0 与 1 相互转化,要求最少的操作次数使任意子序列中不含010101

分析:

不含101以及010,所以只有所有的的0在一边,所有的1在一边这种情况,分别记录前缀01的个数枚举更新答案,最后再与改为全0和全1的操作次数取 min

void solve()
{
    mst(s1, 0), mst(s0, 0);
    idx0 = idx1 = 0;
    res = INF;
    cin >> s;
    s = " " + s;
    int len = s.size() - 1;
 
    for (int i = 1; i <= len; i++)
    {
        s1[i] = s1[i - 1], s0[i] = s0[i - 1];
        if (s[i] == '1')
        {
            idx1++;
            s1[i] = s1[i - 1] + 1;
        }
        else if (s[i] == '0')
        {
            idx0++;
            s0[i] = s0[i - 1] + 1;
        }
    }
 
    for (int i = 1; i <= len; i++)
    {
        int t1 = s1[i] - s1[0] + s0[len] - s0[i];
        int t2 = s0[i] - s0[0] + s1[len] - s1[i];
        res = min(res, min(t1, t2));
    }
    res = min(res, min(idx1, idx0));
    cout << res << endl;
}

C. Game On Leaves

题意:

给定 n 个节点的无根树。两名选手轮流操作,每次可以选择一个叶节点并删除它以及所有和它相连的边,删除节点 x 的选手胜利,判断先手是否有必胜策略。

分析:

必胜态:到最后 x 上有偶数条边

  • 特判:如果 x 刚开始就在叶子节点上,那么先手必然胜利
  • 这时我们可以知道,与 x 节点相连的边数一定 \(\geq 2\)。所以由于两个人都实行最优策略,所以到了仅剩下两条边与 x 相连时就只会开始删其他叶节点来保证必胜态
void solve()
{
    idx = 0;
    cin >> n >> k;
    for (int i = 1, a, b; i < n; i++)
    {
        cin >> a >> b;
        if (a == k || b == k)
            idx++;
    }

    if (idx < 2 || n % 2 == 0)
        cout << "Ayush" << endl;
    else
        cout << "Ashish" << endl;
}

D Guess The Maximums

不会捏,点链接看吧

posted @ 2023-01-09 14:31  347Foricher  阅读(35)  评论(0)    收藏  举报