POJ2348_Euclid's Game_必胜态推理

题意

给定两个整数 a 和 b。Stan 和 Ollie 轮流从较大的数字中减去较小数字的正整数倍,并且相见后的结果不能小于0。Stan先,在自己的回合中将其中一个数变为0的一方获胜。当双方都采取最优策略时,谁会获胜?

思路

假设 b > a (否则可一交换一下)。
如果 b 已经是 a 的倍数,则必胜。
下面讨论 b 不是 a 的倍数的情况:
按照“自由度”的观点可以分为两种情况:
1) b - a < a
2)b - a > a
第一种情况,只能从b中减去a,没有选择的余地。b - a 后得到的是什么状态,它就是相反的状态,是确定的。
第二种情况,存在最大的 x 使 b - a * x < a。那么我们考虑 b - a * (x - 1)。这之后,就变成了第一种情况,没有选择的余地,结果也已经确定。如果之后的状态是必败态,那么选 (x-1) 就可以了。否则,就选 x。因为 b - a * (x-1) 之后是必胜态的话,b - a * x 则为必败态。
综上所述,先遇到自由状态的一方必胜。

参考资料

http://www.cnblogs.com/Knuth/archive/2009/09/05/1561005.html

链接

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

代码

#include<cstdio>
#include<algorithm>

using namespace std;

int a, b;

int main(){
    while(scanf("%d %d", &a, &b) && a && b){
        bool win = true;
        while(1){
            if(a > b) swap(a, b);

            if(b % a == 0) break;
            if(b - a > a) break;
            b -= a;

            win = !win;
        }
        if(win) 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、付费专栏及课程。

余额充值