hdu1527 威佐夫博奕
有2堆石子,有2个人,每个人可以从一堆取或从2堆取一样的个数的石子,至少取1个。
问先手的是胜或输。
设(ak,bk)我么成为局势。 (0,0)(1,2)(3,5)(4,7)。。这种先手必输的叫奇异局势。
bk=ak+k;
三个性质:
1.任意自然数都包含在一个且只有一个奇异局势。
2.任意操作都可将奇异局势变为非奇异局势。如(ak,bk)为奇异局势,
若改变一个,那必定变为非奇异局势。若同时改变2个,bk-ak的并没有改变,
而ak改变,所以一定不是奇异局势。
3.采取适当的方法可以将非奇异局势变为奇异局势。
对于局势(a,b)如果a==b,那取a个后就是奇异局势。如果a=ak,b>bk,那只要取b中b-bk个即可。
如果a=ak,b<bk。从2堆中取走a(k) - a(b-ak)个,就成了(a(b-a(k)) , a(b-a(k))+b-a(k))
局势。如果a>ak,b=ak+k;从1堆拿走a-ak个。如果a<ak,b=ak+k;分2中情况,第一种:a=aj(j<k)
从第二堆拿走b-aj个。第二种:a=bj,从第二堆拿走b-aj个。
根据上面3个性质得到:面对非奇异局势先手必胜。
奇异局势(ak,bk)满足:
ak=(k*(1+sqrt(5))/2;
bk=ak+k;
#include<stdio.h> #include<string.h> #include<math.h> #include<stdlib.h> int main() { int i,j,n,m; double v; while(scanf("%d%d",&n,&m)!=EOF) { if(n>m) { int t=n; n=m; m=t; } double k=n*1.0*(sqrt(5)-1)/2; double bk=n+k; //printf("%.5lf %.5lf\n",bk,m*1.0); if(abs(bk-m*1.0)<1e-8) printf("0\n"); else printf("1\n"); } }