这道题是HDU1527的升级版,题意都好懂,是威佐夫博弈的一道模板题,如果不是很了解威佐夫博弈,可以看一看我写的HDU1527的博客,我大致陈述了威佐夫博弈的一些基本知识,有助于解决此题。这道题目就是判断了当前状态为非奇异局势的时候如何拿走石头使其成为奇异局势,由于数据范围在可接受范围之内,所以先吧0<=k<=1000000的奇异局势存在vis数组内然后,对于所有可能的更改进行暴力找出复合条件的奇异局势即可。
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
int vis[1000005]= {0};
int main()
{
//freopen("in.in","r",stdin);
//freopen("out.out","w",stdout);
for(int i=1; i<1000005; i++)
vis[i]=(int)(i*1.0*(1+sqrt(5))/2);
int n, m;
while(scanf("%d%d",&n,&m)&&(n||m))
{
int k=m-n;
if(vis[k]==n)
{
printf("0\n");
continue;
}
printf("1\n");
if(n>vis[k]&&m>vis[k]+k)
printf("%d %d\n",vis[k],vis[k]+k);
for(int i=1; i<1000005; i++)
if(vis[i]==n)
{
if(m>vis[i]+i)
printf("%d %d\n",vis[i],vis[i]+i);
break;
}else if(vis[i]==m)
{
if(n>vis[i]+i)
printf("%d %d\n",vis[i],vis[i]+i);
break;
}
for(int i=1; i<1000005; i++)
if(vis[i]+i==m)
{
if(n>vis[i])
printf("%d %d\n",vis[i],vis[i]+i);
break;
}else if(vis[i]+i==n)
{
if(m>vis[i]+i)
printf("%d %d\n",vis[i],vis[i]+i);
break;
}
}
return 0;
}