Codeforces 1221 E Game With String —— 不平等博弈

This way

题意:

给你一个串,只包含".“和"X”,你可以将连续的a个".“变成"X”,你的对手则是b个(a>b),你先手,问你最终是否能赢。

题解:

这种博弈的题目我是真不会。。
首先,如果两个".“之间有"X”,那么这两段是不会相互影响的,所以可以一段一段的去考虑。对于长度<b的段我们不用管它,剩余情况分成3类:
1.b<=len<a
2.a<=len<2b
3.2
b<=len
如果其中有一个情况1,那么b必胜,因为b在无路可走的情况下可以拿这一段,同时因为a>b,在这时候a一定没有下一步可以走。那么,如果在a拿完第一次的时候,还有情况3,那么b就可以构造一个长度为b的串。也就是当情况3有两种及以上的时候,b必胜。
接下来是情况3只有1种的时候,为了让a赢,如果情况2有奇数个,那么就是说情况3的长度只能让a拿两次,并且b不能再拿。(因为第一次a必须拿这个串,否则就存在长度>=2*b的了)
如果是2的个数有偶数个,那么a可以拿一次并且剩下两个长度<b的串,或者将其从中间分开,分成两个情况2.

#include<bits/stdc++.h>
using namespace std;
const int N=3e5+5;
char s[N];
int a,b;
int check(){
    int num[4]={0};
    int len=strlen(s);
    int cnt=0,mx=0;
    for(int i=0;i<len;i++){
        if(s[i]=='.')
            cnt++;
        else{
            mx=max(mx,cnt);
            num[1]+=(cnt>=b&&cnt<a);
            num[2]+=(cnt>=a&&cnt<2*b);
            num[3]+=(cnt>=2*b);
            cnt=0;
        }
    }
    mx=max(mx,cnt);
    num[1]+=(cnt>=b&&cnt<a);
    num[2]+=(cnt>=a&&cnt<2*b);
    num[3]+=(cnt>=2*b);
    if(num[1]||num[3]>=2)
        return 0;
    if(!num[3]&&num[2]%2)
        return 1;
    if(!num[3]&&!(num[2]%2))
        return 0;
    if(num[2]%2&&mx>=2*a&&mx<=a+3*b-2)
        return 1;
    if(!(num[2]%2)&&((mx>=a&&mx<=a+2*b-2)||(mx>=3*a&&mx<=a+4*b-2)))
        return 1;
    return 0;
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--){
        scanf("%d%d",&a,&b);
        scanf("%s",s);
        printf("%s\n",check()?"YES":"NO");
    }
    return 0;
}

发布了554 篇原创文章 · 获赞 31 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/tianyizhicheng/article/details/104311746