• 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 }
  • 相关阅读:
    函数指针与变长参数列表
    Finding intersection and union of two sets.
    依赖注入
    可达性分析算法
    java 虚拟机栈
    Java 堆
    java虚拟机>>程序计数器
    Java方法区(Method Area)
    Java 运行时常量池
    java引用
  • 原文地址:https://www.cnblogs.com/AndreMouche/p/1996536.html
Copyright © 2020-2023  润新知