http://wikioi.com/problem/1037/
有一个有趣得取数游戏。初始时,给出一个环,环上得每条边上都有一个非负整数。这些整数中至少有一个时0。然后,将一枚硬币放在环上得一个节点上。二个玩家就是以这个放硬币得节点为起点开始这个游戏,二人轮流取数,取数得规则如下:
(1)选择硬币左边或右边得一条边,并且边上得数非0;
(2)将这条边上的数减至任意一个非负整数(至少要有所减小);
(3)将硬币移到边的另一端。
如果轮到一个玩家走,这时硬币左右两边的边上的数值都是0,那么这个玩家就输了。
如下图所示,描述的时爱丽思和鲍勃两人的对弈过程,其中黑色节点表示硬币所在节点,结果图(d)中,轮到鲍勃走时,硬币两边的边上都是0。所以爱丽思获胜。
现在你的任务是根据给出的环、边上的数值以及起点(硬币所在位置),判断先走方是否有必胜的策略。
博弈游戏,考虑如何使对手必败
如果二手不把他走过的边变为0,那么先手可以在下一步中往回走,也就是走刚才二手走的边,并把这条边变为0,由此,二手则必败。
由此2个人都要把边降为0
如果先手的位置走过奇数步(一直往左走或者往右走),能够到达0这条边之前的那个点,那么先手必胜,否则,先手必败。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
int go[25];
int vis[25];
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>go[i];
}
for(int i=n;i>=1;i--)
{
vis[i]=go[n-i+1];//两个方向
}
int tot1=0;//一边
for(int i=1;i<=n;i++)
{
if(go[i]==0)break;
tot1++;
}
int tot2=0;//另一边
for(int i=1;i<=n;i++)
{
if(vis[i]==0)break;
tot2++;
}
if(tot1%2==1||tot2%2==1)printf("YES\n");//中有一个是偶数
else printf("NO\n");
return 0;
}