博弈专题之-- Euclid's Game HDU - 1525

题目大意:

给两个自然数a,b;用大的减去那个小的 的倍数,这样一直交替进行,知道有人能得到0则获胜。
先手赢,输出 “Stan wins”, 否则 “Ollie wins”。

基本思路:

假设a > b,一开始 f = true ;
直接模拟游戏,进入循环:
首先判断,如果a % b == 0(即 a 是 b 的倍数),或者 a >= 2*b ;则停止。
否则就是a < 2*b,则 a = a - b; f = !f ;这样继续循环;
直到出现0为止。

本来,我疑惑的是为什么a > 2*b,就一定能赢,看了kuangbin的博客,我懂了,感谢。
解释如下:

如果a>=2*b. 那么 那个人肯定知道a%b,b 是 必胜态 还是 必败态。如果是 必败态,先手将 a , b变成 a%b , b,那么先手肯定赢。如果是必胜态,先手将 a, b变成 a%b+b, b.那么对手只有将这两个数变成 a%b, b,先手获胜。

附上代码:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<string>
#include<algorithm>
#include<queue>
#include<stack>
#include<iomanip>
#include<cmath>

using namespace std;
/**
    2018/1/21
    已完成
    **/
int a,b;

int main()
{
    while(scanf("%d%d",&a,&b))
    {
        if(a == 0&& b == 0) break;
        bool f = true;
        if(a < b) swap(a,b);
        while(b){
          if(a%b == 0|| a >= 2*b) break;
          a %= b;
          if(a < b) swap(a,b);
          f = !f;
        }
        if(f) puts("Stan wins");
        else puts("Ollie wins");
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值