CF2123D题解

题目传送门

codeforces

题目思路

思路1(我写爆了,似乎错了)(WA on task 2)

思路1就是可以看出从第\(n-k+1\)到第\(k\)个位置,这些位置满足不管Bob在\(n\)中找任何长度为\(k\)的子串,都会覆盖到这个区间,所以这个区间其实不需要把1改为0,其他都需要,所以直接判断1的总数-上述区间中1的个数是否\(\leq k\)

代码(WA on task 2):

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
    int t;
    cin >> t;
    while (t--)
    {
        vector<int> v;
        int n, k;
        cin >> n >> k;
        string s;
        cin >> s;
        int cnt = 0;
        for (char c : s)
        {
            if (c == '1')
            {
                cnt++;
            }
        }
        int cnt2 = 0;
        int cnt3 = 0;
        for (int j = n - k + 1; j <= k; j++) // 无论如何Bob都会覆盖到的区间。
        {
            if (s[j - 1] == '1')
            {
                cnt2++; // 这些‘1’不需要改成0
            }
            else
            {
                cnt3++;
            }
        }
        if (k >= cnt - cnt2)
        {
            cout << "Alice" << endl;
        }
        else
        {
            cout << "Bob" << endl;
        }
    }
    return 0;
}

思路2(AC)

思路2:
首先如果1的数量\(\leq k\)那么Alice胜
其次如果\(2\times k<=n\)那么Bob必胜,因为思路1中所说的区间不存在,且Alice第一次无法全部置为0,使得场面上Bob操作后始终有 \(>k\) 个1存在。
还有如果初始时存在一段连续的0且长度大于等于\(k\),那么Bob就可以始终保持剩下一个1(因为Bob可以使子串中最初全部为0),所以Bob必胜。
否则Alice还是可以在有限的次数内将所有数字变为0.

代码(AC)

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
    int t;
    cin >> t;
    while (t--)
    {
        vector<int> v;
        int n, k;
        cin >> n >> k;
        string s;
        cin >> s;
        int cnt = 0;
        for (char c : s)
        {
            if (c == '1')
            {
                cnt++;
            }
        }
        if (k >= cnt) // Alice第一轮就可以将所有‘1’改为‘0’,Alice必胜
        {
            cout << "Alice" << endl;
            continue;
        }
        bool flag = false;
        int cnt2 = 0;
        for (char c : s)
        {
            if (c == '0')
            {
                cnt2++;
            }
            else
            {
                if (cnt2 >= k) // 出现了长度超过k的连续‘0’,Bob始终可以剩下一个‘1’,Bob必胜。
                {
                    flag = true;
                    break;
                }
                cnt2 = 0;
            }
        }
        if (cnt2 >= k)
        {
            flag = true;
        }
        if (flag || 2 * k <= n) // 如果2*k<=n的话思路1中的区间必覆盖区间不存在,Bob总能维持至少1个1。
        {
            cout << "Bob" << endl;
        }
        else
        {
            cout << "Alice" << endl;
        }
    }
    return 0;
}


posted @ 2025-07-02 14:19  MichaelZeng  阅读(29)  评论(0)    收藏  举报