hdu2176 取(m堆)石子游戏 nim博弈

    还是nim博弈求先手方案的问题,N堆石子,每次可以选择一堆取走若干个,问先手有多少中取法可以必胜。必胜的话,输出所有方案,即若存在一堆数量为a的石子,取完后还剩下b个可以必胜就输出a b。先取第i堆的话,其他堆异或的结果为B,那么(Ai-x) xor B==0时,说明从Ai中取走x可以留给对手一个必败态,所以对每一堆求出x后,判断一下x是否小于Ai,若小于则答案++,记录下来取法。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long ll;
int n,m;
int a[202000];
int b1[202000],b2[202000];
int main()
{

    while(~scanf("%d",&n) && n)
    {
       int ans=0,ct=0;
       for (int i=1; i<=n; i++)
       scanf("%d",&a[i]),ans^=a[i];
       for (int i=1; i<=n; i++)
       {
           ans^=a[i];
           if (ans<a[i])
           {
               ct++;
               b1[ct]=a[i];
               b2[ct]=ans;
           }
           ans^=a[i];
       }
       if (ct)
       {
           puts("Yes");
           for (int i=1; i<=ct; i++)
           printf("%d %d\n",b1[i],b2[i]);
       }
       else puts("No");
    }
    return 0;
}


你可能感兴趣的:(hdu2176 取(m堆)石子游戏 nim博弈)