CF2123D题解
题目传送门
题目思路
思路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;
}

浙公网安备 33010602011771号