E. Game With String
Problem Link : E. Game With String
Solution:
翻译:
分四种情况:
1,当存在一个线段长度大于等于b小于a,Bob必胜;(因为这个线段只有Bob能覆盖)
2,当至少有两个线段长度至少是2b,Bob永远可以划分其中的一个到情况1从而必胜;(此时Bob可以留一个b给自己)
3,当没有线段长度至少是2b,胜者取决于线段长度>=a的奇偶性;(显然奇数Alice胜否则Bob胜)
4,当正好有一个线段的长度至少是2b,枚举Alice所有可能的在这个线段上的一次动作,然后这种情况就变成了情况3;(到这种情况,除了这个>=2b的,剩余的线段都是>=a的,也就是两个都可以用并且仅用一次的,那么就只用考虑这个线段,一次动作之后会把线段分为两段,Alice会争夺这个分割的机会看能否有机会胜利)
想法很妙,考虑到b < a,那么Bob的优势就在于他能覆盖的线段Alice覆盖不了,再进行深入思考,推出。
AC Code:
int a, b;
char s[maxn];
int n;
int main()
{
int T; scanf("%d", &T);
while(T--){
scanf("%d %d", &a, &b);
scanf(" %s", s + 1);
n = strlen(s + 1);
int cnt = 0;
int cnta = 0, cntb = 0, cnt2b = 0;
int Max_len = 0;
rep(i, 1, n){
if(s[i] == '.') cnt++;
else {
if(cnt >= a) cnta++;
if(cnt >= b) cntb++;
if(cnt >= 2 * b) cnt2b++;
Max_len = qmax(Max_len, cnt);
cnt = 0;
}
}
if(cnt >= a) cnta++;
if(cnt >= b) cntb++;
if(cnt >= 2 * b) cnt2b++;
Max_len = qmax(Max_len, cnt);
if(cntb > cnta) { puts("NO"); continue; }
if(cnt2b >= 2) { puts("NO"); continue; }
if(!cnt2b) { puts(cnta & 1 ? "YES" : "NO"); continue; }
bool f = 0;
rep(i, 0, Max_len - a){
int l_len = i, r_len = Max_len - a - i;
if(l_len >= 2 * b || r_len >= 2 * b) continue;
if(l_len >= b && l_len < a) continue;
if(r_len >= b && r_len < a) continue;
int t = 0;
if(l_len >= a) t++;
if(r_len >= a) t++;
if((t + cnta) & 1) { f = 1; break; }
}
puts(f ? "YES" : "NO");
}
return 0;
}