还是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;
}