Description
有一个有趣得取数游戏。初始时,给出一个环,环上得每条边上都有一个非负整数。这些整数中至少有一个时0。然后,将一枚硬币放在环上得一个节点上。二个玩家就是以这个放硬币得节点为起点开始这个游戏,二人轮流取数,取数得规则如下:
(1)选择硬币左边或右边得一条边,并且边上得数非0;
(2)将这条边上的数减至任意一个非负整数(至少要有所减小);
(3)将硬币移到边的另一端。
如果轮到一个玩家走,这时硬币左右两边的边上的数值都是0,那么这个玩家就输了。
如下图所示,描述的时爱丽思和鲍勃两人的对弈过程,其中黑色节点表示硬币所在节点,结果图(d)中,轮到鲍勃走时,硬币两边的边上都是0。所以爱丽思获胜。
现在你的任务是根据给出的环、边上的数值以及起点(硬币所在位置),判断先走方是否有必胜的策略。

Input
输入:第行一个整数N(N<=20),表示环上的节点数。
第2行N个数,数值不超过30,依次表示N条边上的数值。硬币的起始位置是第一条边与最后一条边之间的节点上。
Output
输出:仅1行。若存在必胜策略,则输出‘YES’,否则输出‘NO’。
Sample Input
样例1:
4
2 5 3 0
样例2:
3
0 0 0
Sample Output
样例1:
YES
样例2:
NO
题解
其实一开始我是这样想的:先手每次把边减到1,后手只能减到0,到了最后一条边,先手减到0,看一看边中1的数量,就能确定有没有必胜策略,但是由于1的位置不一样,所以。。。(我不会写)
可以这样做,先把环拆成链,先手有两个方向可以走,取个或。
先手每次把一条边变成0,可以控制后手的方向,后手也要把他走的下一条边变成0(不然先手还可以从这条路回去,把这条路变成0,后手必输),所以说只要看看最后一条边是不是先手走(就是0之前的边是不是有奇数条)就行了。
#include<iostream> #include<cstdio> using namespace std; const int N=25; int a[N],b[N]; int n,c,d; int main(){ scanf("%d",&n); for (int i=0;i<n;i++){ scanf("%d",&a[i]); b[n-i-1]=a[i]; } for (c=0;c<n,a[c];c++); for (d=0;d<n,b[d];d++); if (c%2||d%2)cout<<"YES";else cout<<"NO"; }