标签:
Sample Input 2 1 2 2 1 1 Sample Output Yes No
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4994
************************************************
题意:有n堆石子,每堆有ai个,每次按照堆的先后顺序至少取走一个石子,最后取完石子的人赢,如果第一个取石子的人赢则输出Yes,否则,输出No。
分析:一开始老是从大于1的上面去判断,后来又琢磨琢磨,才发现只需要对第一个大于1的堆之前等于1的个数来判断就可以了。
如果每堆石子的数目都大于1,则first在取前n-1堆石子时,每次都留下一个石子,在取最后一堆时,一次取完,则first必赢;
但是如果有些堆的石子数不大于1时,当每出现一个大于1的石子堆时,对于取该堆石子的人,他有两种取法,一是全部取走,二是取走ai-1个(即留下1个),而这两种方式在不同的情况中可以使用其中一种使得自己更容易赢。
因此只要判断出从前往后的前n-1堆中,谁先取得第一堆数目大于1的石子堆的主动权,谁就是赢者。
所以只需要求出第一堆数目大于1的石子堆前有多少个1就可以判断了,如果有偶数个1, 则Yes,如果有奇数个1,则No。
AC代码:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <cmath> 6 #include <stack> 7 #include <map> 8 #include <vector> 9 using namespace std; 10 11 #define N 1200 12 #define INF 0x3f3f3f3f 13 14 int a[N]; 15 16 int main() 17 { 18 int T,n,i; 19 20 scanf("%d", &T); 21 22 while(T--) 23 { 24 scanf("%d", &n); 25 26 int ans=0; 27 for(i=0;i<n;i++) 28 scanf("%d", &a[i]); 29 30 for(i=0;i<n-1;i++)///前n-1堆中第一个大于1的堆前的1的个数 31 if(a[i]==1) 32 ans++; 33 else///不为1时要break 34 break; 35 36 if(ans%2==0) 37 printf("Yes\n"); 38 else 39 printf("No\n"); 40 } 41 return 0; 42 }
标签:
原文地址:http://www.cnblogs.com/weiyuan/p/5778064.html