P1290 【欧几里德的游戏】

P1290 【欧几里德的游戏】

真·做题全凭感性


从题目中很容易看出

这是一道\(Gcd\)的题

同时又结合了一些略略的博弈论(丢下锅跑真爽

我们看,辗转相减的\(a,b\)一共只有两种情况

  • \(a-b<b,a>b\),就是\(a\)\(b\)大,但是比$b \(的两倍小,这种情况时。我们的\)S\(和\)O$君就只能硬着头皮去减了。

  • \(a>2b\),就是a比b的二倍大。这时候我们的\(S\)\(O\)君就需要ta们的大脑进行一波用命分析-1s,-1s

  • PS:a b是变量

因为\(a>2b\),所以我们的\(S\)\(O\)君就可以有两种选择

  1. 将a减成小于b,就是进行辗转相除的过程。

  2. 让位,就是在正常进行游戏的前提下,将现在的状态转移给对手(a>b or a < b)。

  3. 通过上面两种骚操作,他肯定就能赢了。

到此,我们就大体分析van了。

另外因为是\(S\)\(O\)君都是极其聪明的(-1s,-1s,用命分析)

所以我们可以看做他们是已经知道自己做出选择后的结果的。

上代码

#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
bool dfs(int a,int b,int who)
{
    if(b==0)//van的游戏结束
        return false;//当前人fail
    if(a/b==1)//第一种情况,只能硬着头皮上
        return !dfs(b,a-b,who^1);
    if(a/b>1)
    {
        /*if(dfs(b,a%b,who^1))//如果我们将a变成小于b的情况,然后对手赢了,我们就可以改命
            return true;//改命
        else
            return true;//如果对手输了,那是更好不过了
        ps:我这里写的有些不大严谨233*/
        return true;//上面的返回都是true
        //至于为什么可以怎么写,一方面是我们利用上面的归纳法总结出来的233
        //也可以这么想,拿到这种情况的人,是可以可以控制a,b的大小的。
        //也就是控制了游戏局数,就像你买了一个5000~6000的挂,神仙一样,为所欲为。(逃
    }
}
int main()
{
    int k;
    scanf("%d",&k);
    int a,b;
    while(k--)
    {
        scanf("%d%d",&a,&b);
        if(a<b)
            swap(a,b);//保证a>b
        if(dfs(a,b,1))//简单的判断,第三个参数其实没有的,只是我调试用的。
            printf("Stan wins\n");
        else
            printf("Ollie wins\n");
    }
}

转载于:https://www.cnblogs.com/Lance1ot/p/9140423.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值