题目思路:威佐夫博弈:
当当前局面[a,b]为奇异局时直接输出0
否则:
1.若a==b,输出(0 0);
2.将a,b不停减一,看能否得到奇异局,若有则输出;
3.由于 ak=q*k(q为黄金分割数)具有单调性,不断改变k的值,看是否可以得到奇异局,若有则输出。
其他的话,要注意一些细节。
#include<stdio.h> #include<string.h> #include<stdlib.h> #include<math.h> #include<iostream> #include<algorithm> #define INF 0x3f3f3f3f #define MAXSIZE 100005 using namespace std; void Game(int a,int b) { double q=(1+sqrt(5.0))/2.0;//黄金分割数 int k=b-a,n,m; if(a==(int)(k*q)) { printf("0 "); return; } else { printf("1 "); if(a==b) { printf("0 0 "); } n=a; m=b; while(n && m)//同时取 { n--; m--; k=m-n; if(n==(int)(k*q) && n!=m) { printf("%d %d ",n,m); break; } } k=b-a; while(1)//单一堆取,k不断向下取 { n=(int)(k*q); m=n+k; if(n<0 || m<0) break; if(n<a && m<b && ((a!=n || b!=m)||(a!=m || b!=n)) && ((n==a||n==b) || (m==a || m==b)))//要求a,b能且只能改变一个数 { printf("%d %d ",n,m); break; } k--; } k=b-a; while(1)//同理单取一堆,k不断向上取 { n=(int)(k*q); m=n+k; if(n>a || m>b) break; if(n<=a && m<=b && ((a!=n || b!=m)||(a!=m || b!=n)) && ((n==a||n==b) || (m==a || m==b))) { printf("%d %d ",n,m); break; } k++; } } } int main() { int a,b; while(scanf("%d%d",&a,&b),a+b) { Game(a,b); } return 0; }