【POJ1067】取石子游戏(威佐夫博弈)

题意:有两堆石子,数量任意,可以不同。游戏开始由两个人轮流取石子。

游戏规定,每次有两种不同的取法,一是可以在任意的一堆中取走任意多的石子;二是可以在两堆中同时取走相同数量的石子。

最后把石子全部取完者为胜者。现在给出初始的两堆石子的数目,如果轮到你先取,假设双方都采取最好的策略,问最后你是胜者还是败者。

 a,b<=1e9

思路:威佐夫博弈,有一个黄金分割点的结论

套公式就好

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 #include<cmath>
 6 typedef long long ll;
 7 using namespace std;
 8 #define N   256
 9 #define oo  10000000
10 #define MOD 1000000007
11 
12 
13 int main()
14 { 
15     int a,b;
16     while(scanf("%d%d",&a,&b)!=EOF)
17     {
18         if(a>b) swap(a,b);
19         double k=b-a;
20         double x=(1+sqrt(5.0))/2.0;
21         int t=k*x+k;
22         if(t==b) printf("0
"); 
23          else printf("1
");
24     }
25     return 0;
26 }
27     

 另一种写法

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 #include<cmath>
 6 using namespace std;
 7 const double GOLD=(sqrt(5)+1)/2.;
 8 int main(){
 9     int a,b,c;
10     while(~scanf("%d%d",&a,&b)){
11         if(a>b) swap(a,b);
12         c=floor(b-a)*GOLD;
13         if(c==a) puts("0");
14         else puts("1");
15     }
16 }