zoukankan      html  css  js  c++  java
  • POJ 1067 威佐夫博弈

    链接:

    http://poj.org/problem?id=1067

    题意:

    威佐夫博弈(Wythoff Game):有两堆各若干个物品,两个人轮流从某一堆或同时从两堆中取同样多的物品,规定每次至少取一个,多者不限,最后取光者得胜。

    题解:

    威佐夫博弈(Wythoff Game):有两堆各若干个物品,两个人轮流从某一堆或同时从两堆中取同样多的物品,规定每次至少取一个,多者不限,最后取光者得胜。
    这种情况下是颇为复杂的。我们用(ak,bk)(ak ≤ bk ,k=0,1,2,...,n)表示两堆物品的数量并称其为局势,如果甲面对(0,0),那么甲已经输了,这种局势我们称为奇异局势。
    前几个奇异局势是:
    (0,0)、(1,2)、(3,5)、(4,7)、(6,10)、(8,13)、(9,15)、(11,18)、(12,20)。
    可以看出,a0=b0=0,ak是未在前面出现过的最小自然数,而 bk= ak + k。
     
    两个人如果都采用正确操作,那么面对非奇异局势,先拿者必胜;反之,则后拿者取胜。
    那么任给一个局势(a,b),怎样判断它是不是奇异局势呢?我们有如下公式:
    ak =[k(1+√5)/2],bk= ak + k (k=0,1,2,...n 方括号表示取整函数)
    奇妙的是其中出现了黄金分割数(1+√5)/2 = 1.618...因此,由ak,bk组成的矩形近似为黄金矩形,由于2/(1+√5)=(√5-1)/2,可以先求出j=[a(√5-1)/2],若a=[j(1+√5)/2],那么a = aj,bj = aj + j,若不等于,那么a = aj+1,b = aj + j + 1,若都不是,那么就不是奇异局势。然后再按照上述法则进行,一定会遇到奇异局势。

    代码:

    31 int main() {
    32     int a, b;
    33     while (cin >> a >> b) {
    34         if (a > b) swap(a, b);
    35         int k = b - a;
    36         if (int((sqrt(5.0) + 1) / 2.0 * k) == a) cout << 0 << endl;
    37         else cout << 1 << endl;
    38     }
    39     return 0;
    40 }
  • 相关阅读:
    数学
    ACM之路
    归并排序(分治法,nlogn,较为稳定)
    字典树基础模板
    c语言对象(函数,类,变量)的声明与定义
    typedef的高级用法---------理解函数声明
    4503: 两个串
    HDU 5972 Regular Number
    HDU 5215 Cycle
    Hihocoder #1513 : 小Hi的烦恼
  • 原文地址:https://www.cnblogs.com/baocong/p/6782432.html
Copyright © 2011-2022 走看看