题目链接:hdu 2177
威佐夫博弈水题,如果不是奇异局势需要输出走完第一步石堆的状态,先按两堆取相同石子,再按只取一堆。
可以打表解决
#include<iostream>
#include<cstdio>
#include<vector>
#include<set>
#include<map>
#include<string.h>
#include<cmath>
#include<algorithm>
#include<queue>
#include<stack>
#define LL long long
#define mod 1000000007
#define inf 0x3f3f3f3f
#define sqr(a) (a)*(a)
#define lan(a,b) memset(a,b,sizeof(a))
using namespace std;
struct node
{
int x,y;
} ;
node num[2000010];
int vis[2000100];
int s[2000010][2];
void init()
{
lan(vis,0);
int k=1;
s[0][0]=0;
s[0][1]=0;
for(int i=1;i<=1000000;i++)
{
if(vis[i]!=1)
{
s[k][0]=i;
s[k][1]=i+k;
num[i].x=1;
num[i].y=k;
num[i+k].x=2;
num[i+k].y=k;
vis[i]=1;
vis[i+k]=1;
k++;
}
}
}
int main()
{
init();
int a,b;
while(~scanf("%d%d",&a,&b))
{
if(a==0&&b==0)
break;
if(a>b)
{
int t=a;
a=b;
b=t;
}
int k=b-a;
if(s[k][0]==a&&s[k][1]==b)
{
printf("0\n");
continue;
}
printf("1\n");
if(s[k][0]<a)
{
printf("%d %d\n",s[k][0],s[k][1]);
if(num[b].x==2&&s[num[b].y][0]<a) printf("%d %d\n",s[num[b].y][0],s[num[b].y][1]);
if(num[a].x==2&&s[num[a].y][1]<b) printf("%d %d\n",s[num[a].y][0],s[num[a].y][1]);
}
else if(s[k][0]>a)
{
if(num[a].x==1&&s[num[a].y][1]<b) printf("%d %d\n",s[num[a].y][0],s[num[a].y][1]);
if(num[a].x==2&&s[num[a].y][1]<b) printf("%d %d\n",s[num[a].y][0],s[num[a].y][1]);
}
}
return 0;
}