题目的意思是给你一个多边形,每条边上有一个权值,你开始在第一个点。每次你必须经过一条有权值的边,并且把该边的权值减小到任意一个非负值,到达该边的另外一个点。
谁第一个无法操作就算输。
题意很简单,解法也很简单。
这样考虑,题目说明了在给定的边中一定有一条边为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 "); 18 else printf("NO "); 19 } 20 return 0; 21 }