url
大意:
alice和bob进行博弈。给定一个字符串由X和.组成,每个人每次进行一次 *** 作为将连续数量的"."变成"X",其中alice每次要求的连续数量为a,bob为b,且a>b.
alice先手。问是否能让alice必胜。
思路:
惊奇地发现这是一个非公平博弈(bob占优势,可恶,可怜的alice!),一开始想着SG函数去做,打算用状压来处理情况的,但是思路乱的不行,还是放弃了。
发现每一段连续的"."都是互不干扰的,所以我们可以一段一段来看。
设连续的长度为len。
1.len
很好,大家都没得玩,谁都放不了,不必考虑。
2.len>=b&&len
只有bob能放。这时bob必赢,因为Alice能放的bob都能放,如果哪次bob除了这一段len已经没有选择了,就说明alice也同样没有选择了,那么bob只要放在这里游戏就结束了。
3.len>=a&&len<2*b:
大家都只能在这里放一次,一次性用品。
4.len>=2*b:
对bob来说算是很长的区间了。如果对于这个区间bob能够先手的话,他一定可以构造出一个2类区间,那他就赢了。所以只要有两个这样的区间,bob就同样一定赢了。如果0个的话,那大家就算公平竞争了,一人用一段3类区间,看谁倒霉刚好轮空就是了。(考虑3类区间的奇偶性).接下来就是只有一个4类的情况了。那么考虑alice先手:她会选择尽可能截断这个长区间,并且要保证两边的多出来的区间不是2类也不是4类(2类不用说了,如果有四类的话,那bob就可以构造出一个2类,那他也必胜),如果能做到这个的话,那她就能跟bob公平竞技了,同上,考虑3类的奇偶性。同时注意,还要加上alice截断后可能产生的3类区间。
(真是伤脑壳。。。)
#include
using namespace std;
#define ll long long
ll n,k;
ll t;
char s[300010];
ll a,b;
bool solve()
{
bool c33=0;
ll len;
ll c1=0,c2=0,c3=0;
for(int l=1,r=1;l<=n;l=r+1,r=l)
{
if(s[r]=='X') continue;
while(r=b&&d=a&&d<2*b)//一人一个
{
c2++;
continue;
}
if(d>=2*b)
{
c3++;
len=d;
continue;
}
//printf("%lld\n",d);
}
//cout<=2)
{
//cout<<"NO"<=b&&llen=b&&rlen=2*b) continue;
if(rlen>=2*b) continue;
fsd=1;
num=(llen>=a&&llen<2*b)+(rlen>=a&&rlen<2*b);
if((c2+num)%2==0) return 1;
}
}
return 0;
}
int main()
{ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
scanf("%lld",&t);
while(t--)
{
scanf("%lld%lld",&a,&b);
scanf("%s",s+1);
n=strlen(s+1);
if(solve()) printf("YES\n");
else printf("NO\n");
}
return 0;
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)