1.判断输赢用公式
2.判断步骤按下面的规律
当两堆数量为 a,b(b>=a)时,假设奇异局势为m(k) n(k)
因为a要不在m(k)中,要不在n(k)中
当a在m(k)中
a=m(k),b>n(k): b堆去b-n(k)个
a=m(k),b<n(k): 都为m[b-a],n[b-a]个,则,a、b堆同时减去a-m[b-a]或b-n[b-a]个
当a在n(k)中
a=n(k),b>m(k): b堆减去b-m(k)个
a=n(k),b<m(k): 如果b=m(j),则在a堆里拿走a-n(j);
如果b=n(j),则在a堆里拿走a-m(j);
/*HDOJ2177
作者:陈佳润
2013-04-02
*/
#include<iostream>
using namespace std;
#include<math.h>
long int m[1000005],n[1000005];
long int binaryCheck(long int check[],long int value,long int left,long int right){
long int mid=(left+right)/2;
if(value==check[mid])
return mid;
if(left>=right)
return -1;
if(value>check[mid])
binaryCheck(check,value,mid+1,right);
else
binaryCheck(check,value,left,mid);
}
int Wythoff(int a,int b)
{
int t;
if(a>b)
{
t=a;a=b;b=t;
}
double temp=(1+sqrt(5.0))/2;
if(a==int((b-a)*temp))
return 0;
else
return 1;
}
int main()
{
double gold=((1+sqrt(5.0))/2);
long int i,a,b,k;
for(i=0;i<=1000000;i++)
{
m[i]=long int(i*gold);
n[i]=m[i]+i;
}
while(scanf("%ld%ld",&a,&b)!=EOF&&(a||b)){
if(Wythoff(a,b))//判断赢或输
printf("1\n");
else{
printf("0\n");
continue;
}
//计算a的位置
printf("%ld %ld\n",m[b-a],n[b-a]);//同时减
//减一方
k=binaryCheck(m,a,0,1000000);
if(k==-1){
k=binaryCheck(n,a,0,1000000);
if(b>m[k])
printf("%ld %ld\n",m[k],a);
}else{
if(b>n[k])
printf("%ld %ld\n",a,n[k]);
}
}
return 0;
}