题目传送门:
http://poj.org/problem?id=2975
http://acm.hdu.edu.cn/showproblem.php?pid=2176
因为两题都差不多,所以我就放在一起写啦。
n堆石子,然后问如果必胜的话有多少种移动方法(一步)。
因为答案最多只有n,令ans=a1^a2^…^an。
如果需要构造出异或值为0的数,而且由于只能操作一堆石子,所以对于某堆石子ai,现在对于ans^ai,就是除了ai以外其他的石子的异或值,如果ans^ai<=ai,那么对于ai的话,是可以减小到ans^ai的值,然后使得所有数 的异或值为0,也即转移到了必败态。
POJ:
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
int a[200000];
int main (void)
{
int t;
// cin>>t;
while(~scanf("%d",&t))
{
if(t==0)
{
break;
}
int xx=0;
for(int i=0;i<t;i++)
{
scanf("%d",&a[i]);
xx^=a[i];
}
if(xx==0)
{
printf("No\n");
continue;
}
printf("Yes\n");
for(int i=0;i<t;i++)
{
int re=xx^a[i];
if(a[i]>=re)
{
printf("%d %d\n",a[i],re);
}
}
}
return 0;
}
HDU:
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
int a[200000];
int main (void)
{
int t;
// cin>>t;
while(~scanf("%d",&t))
{
if(t==0)
{
break;
}
int xx=0;
for(int i=0;i<t;i++)
{
scanf("%d",&a[i]);
xx^=a[i];
}
if(xx==0)
{
printf("No\n");
continue;
}
printf("Yes\n");
for(int i=0;i<t;i++)
{
int re=xx^a[i];
if(a[i]>=re)
{
printf("%d %d\n",a[i],re);
}
}
}
return 0;
}