Game With String(CF 1221 E)
题目大意
\(Alice\)和\(Bob\)玩一个字符游戏,字符中只有
.和X,每次\(Alice\)可以把一串长度为\(a\)的.全变成X,\(Bob\)可以把一串长度为\(b\)的.变成X\((a>b)\)。有\(q\)组询问,每次给你一个只有.和X的字符串以及\(a,b\),\(Alice\)为先手,问\(Alice\)能否胜利。\((1\le q\le3\times10^5,1\le b<a\le3\times10^5,1\le|s|\le3\times10^5,\sum|s|\le3\times10^5)\)
思路
我们把全为
.的连续的串分为四类:\[\begin{cases} len<b(1)\\ b\le len<a(2)\\ a\le len<2\times b(3)\\ len\ge2\times b(4) \end{cases} \]这样,如果有第二种情况或两次及以上的第四种情况,\(Alice\)是必败的,然后我们来看只有一次第四种情况的情况。在这种情况中,\(Alice\)占了一个位置后,把它分成了左右两个位置,如果左右两边会有第二种或第四种的话,\(Alice\)也是必败的,只有能转化成第一种或第三种才行,如果能的话,我们就看一下第三种的奇偶性就可以了,然后这道题就做完了。
代码
#include<bits/stdc++.h>
using namespace std;
char s[300005];
int aa[300005];
int main()
{
int _;
scanf("%d",&_);
while(_--)
{
int a,b;
scanf("%d%d",&a,&b);
scanf("%s",s+1);
int n=strlen(s+1);
int cnt=0;
int tot=0;
int t2=0,t3=0,t4=0;
int len=0;
for(int i=1;i<=n;i++)
{
if(s[i]=='.')tot++;
else if(tot)
{
aa[++cnt]=tot;
if(tot>=b&&tot<a)t2++;
if(tot>=a&&tot<2*b)t3++;
if(tot>=2*b){t4++;len=tot;}
tot=0;
}
}
if(tot)
{
aa[++cnt]=tot;
if(tot>=b&&tot<a)t2++;
if(tot>=a&&tot<2*b)t3++;
if(tot>=2*b){t4++;len=tot;}
}
if(t2){printf("NO\n");continue;}
if(t4>=2){printf("NO\n");continue;}
if(t4==0)
{
if(t3&1){printf("YES\n");continue;}
else {printf("NO\n");continue;}
}
if(len<a)continue;
bool ck=0;
for(int l=0;len-a-l>=0;l++)
{
int r=len-a-l;
int num=t3;
if(l>=b+b||(b<=l&&l<a))continue;
if(r>=b+b||(b<=r&&r<a))continue;
if(l>=a)num++;
if(r>=a)num++;
if((num&1)==0)ck=1;
}
if(ck)printf("YES\n");
else printf("NO\n");
}
return 0;
}

浙公网安备 33010602011771号