HDU 1850——Being a good boy

 题目链接: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\n");
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\n", ans);
42         }
43     }
44     return 0;
45 }

 

posted @ 2016-08-06 16:43  shadervio  阅读(122)  评论(0编辑  收藏  举报