ZOJ2686_Cycle Gameu

题目的意思是给你一个多边形,每条边上有一个权值,你开始在第一个点。每次你必须经过一条有权值的边,并且把该边的权值减小到任意一个非负值,到达该边的另外一个点。

谁第一个无法操作就算输。

题意很简单,解法也很简单。

这样考虑,题目说明了在给定的边中一定有一条边为0,也就是说给的是一条链,实际上不是环。

结论是这样的,先手的人可以有两个方向走,如果任意一个方向上有奇数条权值大于0的边,那么先手必胜,如果任意一个方向上的离0边的距离都为偶数或0,那么就是必输。

证明也很简单。

假设在任意一个方向上恰好有奇数条边,那么一开始先手的人可以通过这条边,并且把该边的权值减少到0;那么接下来,另一个游戏者必须沿着该方向走,而且只有两种选择,那就是对于接下来这边边是否减少到0。如果使边权减少到0,那么显然先手的人只要继续把下一条边减少为0就可以获胜了;假如不把比比安全减少到0,那么先手可以在下一点回走一步,并且把比边权减少到0,这样这是一个孤立的点了,后手无法行动。于是就得出了有必胜的策略。

对于两天的边数都不为奇数的情况为必败态也是很显然的。只需要按上面的思路假设两种情况就得出结论了。 贴代码:

 

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 using namespace std;
 5 
 6 int a[66],n,m,k,ans1,ans2,t;
 7 
 8 int main()
 9 {
10     scanf("%d",&t);
11     while (t--)
12     {
13         scanf("%d",&n);
14         for (int i=1; i<=n; i++) scanf("%d",&a[i]);
15         for (ans1=0; a[ans1+1]!=0; ans1++) ;
16         for (ans2=0,k=n; a[k]!=0; ans2++,k--) ;
17         if ((ans1&1) || (ans2&1)) printf("YES\n");
18             else printf("NO\n");
19     }
20     return 0;
21 }

 

 

posted @ 2013-10-18 19:24  092000  阅读(322)  评论(0编辑  收藏  举报