题目链接:Balloon Game
题目大意:
Alice 和 Bob进行一个博弈游戏,他们要摆放气球,保证颜色一样的气球全部相邻出现,现在在一个序列中气球有一部分已经摆放,还有一些未摆放,用"?"表示。比如:a?b?c,那么最后我们能摆放成aabbc,aabdc......
Alice先手摆放气球,他想让气球的颜色种数为奇数个,Bob后手放,想让颜色种数为偶数个,问对于每个询问Alice是否有必胜策略。
题目分析:
第一次看完题目的时候,觉得对于这个博弈问题一些情况是可以解决的:
1.当出现"a?...?a"这种情况下时,中间一段其实已经确定了是"a",所以只有当Alice和Bob不想改变其他现有格局的气球才会放一个,然后他们都会交替的放颜色确定的气球,所以他们的奇偶性能够“反转”最后的结果。
2.当出现"a?...?b"这种情况下时,如果先手不想再增加颜色,完全可以在最后一个b前放个"a",那么这一段的"?"也变成了情况1。
3.当出现"a?...?b"这种情况下时,如果先手想增加颜色的话,那么他会在哪里增加一个新颜色是关键。不管在哪里添加一个新的颜色,我们都会把"?...?",拆成两个序列,这里就需要奇偶讨论了。
1)当"a?...?b"中的"?"个数为偶数个,那么增加一个颜色,会把其拆成一奇一偶两个"???"序列。这种情况其实与单个"a?...?b"中的"?"个数为奇数个一样的。
2)当"a?...?b"中的"?"个数为奇数个,那么增加一个颜色,会把其拆成两偶两个"???"序列。这种情况其实与单个"a?...?b"中的"?"个数为偶数个一样的。
综上所述,能否有必胜的策略的因素有:1)现有颜色个数;2)不确定颜色的气球的奇偶性;3)确定颜色的气球的奇偶性
不过在训练时我没有敢去做的原因是当时以为要考虑到颜色只有26种,那么判断将相当复杂,因为我们要考虑剩下的颜色个数等等。。。不过后来看到hint里有一句:“Though the showing colors in input case will only be a
- z
, you can use any color.” QAQ~~~
所以看清题目还是最关键啊~
/*author:Samsons date:2015.4.12*/ #include <cstdio> #include <cstdlib> #include <cstring> #include <iostream> using namespace std; int color[26]; int main() { //freopen("b.in","r",stdin); memset(color,0,sizeof(color)); char tmp=‘\0‘; int num,num_s,num_n,num_co,ans,i; num=0;num_s=0;num_n=0;num_co=0; char ch; while (scanf("%c",&ch)!=EOF) { if (ch==‘?‘) { num++; continue; } if (tmp!=ch) { color[ch-‘a‘]=1; num_n+=num; tmp=ch; num=0; } else { color[ch-‘a‘]=1; num_s+=num; tmp=ch; num=0; } } num_n+=num; for (i=0;i<26;i++) if (color[i]==1) num_co++; if (num_n==0) { if (num_co % 2==1) { cout<<"Yes"<<endl; } else { cout<<"No"<<endl; } return 0; } if (num_n==1) { cout<<"Yes"<<endl; return 0; } ans=0; if (num_n % 2==1) ans=1; if (num_s % 2==1) if (ans==1) ans=0; else ans=1; if (ans==1) cout<<"Yes"<<endl; else cout <<"No"<<endl; return 0; }