威佐夫博弈

有两堆石子,数量任意,可以不同。游戏开始由两个人轮流取石子。游戏规定,每次有两种不同的取法,一是可以在任意的一堆中取走任意多的石子;二是可以在两堆中同时取走相同数量的石子。最后把石子全部取完者为胜者。现在给出初始的两堆石子的数目,如果轮到你先取,假设双方都采取最好的策略,问最后你是胜者还是败者。
Input
输入包含若干行,表示若干种石子的初始情况,其中每一行包含两个非负整数a和b,表示两堆石子的数目,a和b都不大于1,000,000,000。
Output
输出对应也有若干行,每行包含一个数字1或0,如果最后你是胜者,则为1,反之,则为0。
Sample Input
2 1
8 4
4 
Sample Output
0
1
0
#include<stdio.h>
#include<math.h>
double g=(sqrt(5.0)+1)/2;
int main()
{
    int a,b,t;
    while(scanf("%d %d",&a,&b)==2)
    {
        if(a>b)
        {
            t=a;
            a=b;
            b=t;
        }
        int k=b-a;
        if(a==(int)(g*k))
        {
            printf("0\n");
        }
        else
        {
            printf("1\n");
        }

    }
    return 0;
}

分析
   
   
  1. (0,0) 先手必败,很明显他没得取了。
  2. (1,2) 先手必败。具体分析一下,先手有以下几种取法:  取第一堆的1个,后手取走第二堆的2个获胜。  从第一堆第二堆各取1个,后手取走第二堆剩下的1个获胜。  取第二堆的1个,后手从第一堆第二堆各取1个获胜。  取第二堆的2个,后手取走第一堆的1和获胜。  综上所述,先手必败。
  3. (3,5) 先手必败。 首先可以明确的一点是,先手不能把任意一堆取完,如果取完显然必败。  先讨论先手从第一堆中取的情况  先手可以从第一堆中取1个,后手从第二堆中取4个,转化为(1,2),先手必败。  先手可以从第一堆中取2个,后手从第二堆中取3个,转化为(1,2),先手必败。  再讨论先手从第二堆中取的情况  先手可以从第二堆中取1个,后手从两堆中各取2个,转化为(1,2),先手必败。  先手可以从第二堆中取2个,后手从两堆中各取3个,转化为(0,0),先手必败。  先手可以从第二堆中取3个,后手从两堆中各取1个,转化为(1,2),先手必败。  先手可以从第二堆中取4个,后手从第一堆中取2个,转化为(1,2),先手必败。  接着讨论先手从两堆中取的情况  先手可以从两堆中各取1个,转化为(2,4),此时情况较多  后手足够聪明,他从第二堆中取了1个,转化为(2,3),先手也足够聪明,他为了不直接输掉,从第一堆中取了1个(其他取法直接输掉了),转化为(1,3),此时后手从第二堆中取1个,转化为(1,2),先手必败。  先手可以从两堆中各取2个,后手从第二堆中取一个,转化为(1,2),先手必败。  综上所述,先手必败。
  4. 其他的先手必败局势  (4,7),(6,10),(8,13),(9,15),(11,18).

  5. 我们将先手必败局势的集合,称为奇异局势。

奇异局势的性质

  1. 任何自然数都包含在一个且仅有一个奇异局势中。
  2. 任意操作都可将奇异局势变为非奇异局势。
  3. 采用适当的方法,可以将非奇异局势变为奇异局势。

Betty定理

我们可以发现,将所有奇异局势按照第一堆的石子的数目从小到大排列,每个奇异局势的差值是自然数列。  进一步观察发现,对于一个奇异局势(A,B), A = 下取整[ (B-A) * 1.618 ],更准确的说,1.618 = (sqrt(5) + 1) / 2.

为什么会是这样的? 具体的证明涉及到Betty的定理,有兴趣的读者可以百度,这里不再赘述。

常见的几类问题

  1. 给出一个局面,判断先手输赢。  检查是否是奇异局势。
  2. 给出局面,判断先手输赢,若赢,求出首步取法。  由于差值是固定的,根据差值计算。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值