HDU 1850 Being a Good Boy in Spring Festival

题意:对于Nim游戏:有n堆石子,每堆有a[i]个,两人轮流从任意堆中取任意多的石子(一次不能同时从多堆中拿),

每次至少取一个,多者不限,最后取光者胜。先手的人如果想赢,一共有几种选择?

/*先手必胜的情况,当在n堆石子中存在其中一堆石子a[i]的数量大于其他堆的异或a[i]^sum。
此时先拿的人可以在a[i]中取走一部分,使得啊a[i]剩下的那部分和其他堆的异或相等,则先拿的那个人必赢。
有多少个这样的a[i],先拿的人就有多少种必胜的可能。

若所有堆的石子的异或为0,则先拿的必败。*/

  1. /* 
  2. 可选步数为任意步,SG(x) = x;  
  3. 本题中每一堆都可以选任意个,所以每一堆的SG值都是所剩余的个数。 
  4. 最后结果是所有堆的SG值异或的结果。令ans = 所有堆的SG值异或的结果 
  5. 如果ans == 0,则是必败点。 
  6. 如果ans != 0,使取后结果为0的策略是必胜策略 
  7. 具体怎么取呢? 
  8. 每一堆的数值与ans相异或,所得的结果就是这一堆可以取的数量。 
  9. 但是,如要这一堆数量没有这么多,就不可以这么取 
  10. */ 

#include <iostream>
using namespace std;
int a[100];
int main()
{
    int t;
    int i,sum;
    while(cin>>t&&t)
    {
        sum=0;
        for(i=1;i<=t;i++)
        {
            cin>>a[i];
            sum^=a[i];
        }
        int j;
        int ans=0;
        for(j=1;j<=t;j++)
        {
            if(a[j]>(a[j]^sum))
                ans++;
        }
        cout<<ans<<endl;
    }
    return 0;
}


你可能感兴趣的:(HDU 1850 Being a Good Boy in Spring Festival)