题目大意:
给你一个只含字符'A'和'B'的串,A和B两人轮流对其中的子串染色,要求被染色的子串中不包含已经被染色的子串。
最后,如果一方染的'A'少,那么这一方胜;
如果双方染的'A'和'B'一样多,那么就是平局。
问哪一方有必胜策略,或是都没有必胜策略。
思路:
首先可以想到一个贪心的做法:
当字符串中还有'B'的时候,取一段全'B'子串;
当字符串中只剩下'A'的时候,不得不取'A',这时候双方轮流取一个。
显然,当'A'的数量为偶数时,由于双方都轮流取一个'A',最后双方取的'A'一样多,那么一定是平局。
当'A'的数量为奇数时,显然有一方会多取一个'A',而且一定是先开始取'A'的一方输。
那么问题就转化成了如果只取'B',最后不能取的一方输(因为只能取'A'了)。
这就变成了一个经典的Nim游戏模型。
我们把每一段连续的'B'当作一个子游戏,把'B'的数量当作游戏的状态。
对于一个状态x,sg(x)=mex{sg(y)|y是x的后继状态}。
显然,由于题目没有特殊的限制,x的后继状态总是0~x-1的所有状态。
那么显然sg(x)=x。
#include<cstdio>
#include<cctype>
inline int getint() {
register char ch;
while(!isdigit(ch=getchar()));
register int x=ch^'';
while(isdigit(ch=getchar())) x=(((x<<)+x)<<)+(ch^'');
return x;
}
inline char getupper() {
register char ch;
while(!isupper(ch=getchar()));
return ch;
}
inline int getsg(const int &x) {
return x;
}
int main() {
int n=getint();
int tota=,ans=,cnt=;
for(int i=,ch='\0',last;i<=n;i++) {
last=ch;
ch=getupper();
if(ch=='A') {
tota++;
if(last=='B') {
ans^=getsg(cnt);
cnt=;
}
} else {
cnt++;
}
}
ans^=getsg(cnt);
if(tota&) {
puts(ans?"A":"B");
} else {
puts("-1");
}
return ;
}