题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1850
题目大意:桌上有m堆扑克牌,数量为ni(1<=i<=m),每次可以取走任意一堆的牌堆取走任意的牌,问怎样先手才能赢。
解题思路:用到异或算法+博弈思想
1.首先要判断先手的局面是不是奇异局势,判断方法:a^b^c^.....看是否等于0,如果不为0,则说明不是奇异局势。
2.既然局面不是奇异局势了,那么根据尼姆博奕里面的知识,肯定有一个方法,就是改变某个数值后使得a^b^c....=0;
so代码如下:
1 #include <cstdio> 2 #include <iostream> 3 4 using namespace std; 5 6 int a[105]; 7 8 int main() 9 { 10 int m, nimSum; 11 while(scanf("%d", &m) != EOF && m) 12 { 13 nimSum = 0; 14 for(int i=0; i<m; i++) 15 { 16 scanf("%d", &a[i]); 17 nimSum ^= a[i]; 18 } 19 if(nimSum == 0) 20 { 21 printf("0 "); 22 } 23 else 24 { 25 int temp = nimSum, k, cur=0; 26 while(temp) 27 { 28 if(temp&1) 29 k=cur; 30 temp >>= 1;//相当于/2,位运算 31 cur++; 32 } 33 int ans=0; 34 for(int i=0; i<m; i++) 35 { 36 if((a[i]>>k) & 1) 37 { 38 ++ans; 39 } 40 } 41 printf("%d ", ans); 42 } 43 } 44 return 0; 45 }