POJ 1067 取石子游戏【威佐夫博奕】


POJ 1067 取石子游戏
大意:有两堆石子,数量为A,B.两个玩家轮流从中取石子,每次可从一堆中取若干颗或从两堆中取相同数目石子,
最后取完者为胜,问先取者是否有必胜策略?
分析:
  比较裸的威佐夫博奕(Wythoff Game)
  有黄金分割知,不安全局面(an,bn)满足:
  an = floor(a*n),bn = floor(b*n);
  其中:
    a = (1+sqrt(5))/2
 b = (3+sqrt(5))/2
  在本题中,已知石子个数A,B,判断A,B是否能满足上述条件,即
  若存在n能使得:
  floor(n*a)==A,floor(n*b)==B    (1)
  那么便必输,否则必胜
  逆推上式,若存在该n,则 n = ceil(A/a),然后再判断(1)是否成立即可。
  特别注意:在n的求解中必须向上取整!

View Code
1 #include<stdio.h>
2 #include<math.h>
3 const double alpha = (1.0+sqrt(5.0))/2.0;
4 const double beta = (3.0+sqrt(5.0))/2.0;
5
6 int main()
7 {
8 __int64 a,b;
9
10 while(scanf("%I64d%I64d",&a,&b)!=EOF)
11 {
12 if(a>b)
13 {
14 __int64 temp = a;
15 a = b;
16 b=temp;
17 }
18
19 __int64 n = (ceil)(a/alpha); //必须向上取整
20 __int64 ta = (__int64)(alpha*n);//注意强制类型转换的书写格式
21 __int64 tb = (__int64)(beta*n);
22 if(ta==a&&tb==b)
23 printf("0\n");
24 else
25 printf("1\n");
26 }
27 return 0;
28 }
posted @ 2011-03-26 21:06  AndreMouche  阅读(659)  评论(0编辑  收藏  举报