标签:
题意:威佐夫博弈原型,除了输出先手能不能胜,还要输出先手的第一手选择。
思路:预处理出1000000以内的所有奇异局势。对于每个自然数,其必然是某一个奇异局势的a或者b。故对于一个非奇异局势,必定有一个且一个只取一堆石子的操作使得当前局势变成奇异局势。
#include<stdio.h> #include<string.h> #include<math.h> #include<iostream> using namespace std; int a[400000],b[400000]; void init(){ for(int i=0;;i++){ a[i]=i*(1+sqrt(5.0))/2; b[i]=a[i]+i; if(b[i]>1000000){ break; } } } int main(){ init(); int n,m; while(~scanf("%d%d",&n,&m)&&n){ if(n>m) swap(n,m); int t=(m-n)*(1+sqrt(5.0))/2; if(n==t){ printf("0\n"); continue ; } puts("1"); int ans[2][2]={0},js=0; for(int i=0;;i++){ if(a[i]>n||b[i]>m) break; if(n-a[i]==m-b[i]){ ans[0][0]=ans[0][1]=n-a[i]; js++; } if(a[i]==n){ ans[1][1]=m-b[i]; js++; } if(b[i]==n){ ans[1][1]=m-a[i]; js++; } if(a[i]==m){ ans[1][0]=n-b[i]; js++; } if(b[i]==m){ ans[1][0]=n-a[i]; js++; } if(js==2) break; } if(ans[0][0]) printf("%d %d\n",n-ans[0][0],m-ans[0][1]); if(n!=m)n-=ans[1][0],m-=ans[1][1]; else n-=ans[1][0]; if(n>m) swap(n,m); printf("%d %d\n",n,m); } return 0; }
标签:
原文地址:http://www.cnblogs.com/L-King/p/5762405.html