• Euclid`s Game


    题目

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

    分析

    不妨设 a<b,

    情况一:若b<2a,则(a, b)只能变成(a, b-a);一旦出现 b%a==0,则先手赢。

    情况二:若b>2a,则(a, b)可变成(a, b%a+a),回到了第一种情况。先手每次都能变回情况一,后手每次只能b-a,总会出现a|b,先手就能赢。也就是说这种情况先手必赢。

    //还是可以套用打表模板,只是需要加上两条必胜情况的判断,不然时间复杂度太高

    //在先手不能必赢的情况下,如果后手sg值不全为0,先手还能平局;如果后手sg值全为0,先手必败

    #include<cstdio>
    #include<algorithm>
    #include<map>
    using namespace std;
    
    
    typedef  long long ll;
    typedef pair<ll, ll> P;
    const int maxn = 50;
    map<P, int>mp;
    
    int dfs(ll a, ll b)  //必胜返回1,平局返回2,必败返回-1
    {
        //printf("%lld %lld
    , a, b);
        if(a < b)  swap(a, b);
        int& ret = mp[make_pair(a, b)];
        if(ret)  return ret;
        if(a == 0 || b == 0)  return ret=-1;
        if(a % b == 0)  return ret=1;       //
        if(a - b > b)  return ret=1;        //加了两条必胜判断
        bool flag = false;       //能否成平局
        for(ll i = 1;b*i <= a;i++)
        {
            int tmp = dfs(a-b*i, b);
            if(tmp == -1)  return ret=1;    //后面存在必败态,先手必胜
            if(tmp == 2)  flag = true;  //存在平局
    
        }
        return ret=(flag ? 2 : -1);
    }
    
    int main()
    {
    
        ll a, b;
        while(scanf("%lld%lld", &a, &b) == 2 && a)
        {
            if(dfs(a, b) == 1)  printf("Stan wins
    ");
            else  printf("Ollie wins
    ");
        }
        return 0;
    }

    简化版:

    #include<bits/stdc++.h>
    using namespace std;
    
    int a, b;
    
    void solve()
    {
        bool flag = true;
        while(true)
        {
            if(a > b)  swap(a, b);
            if(b % a == 0)  break;
            if(b -a > a)  break;      //情况二
            b -= a;       //情况一
            flag = !flag;
        }
        if(flag)  printf("Stan wins
    ");
        else  printf("Ollie wins
    ");
    }
    
    int main()
    {
        while(scanf("%d%d", &a, &b) == 2 && a)
        {
            solve();
        }
    
        return 0;
    }
  • 相关阅读:
    JVM参数说明介绍
    使用Intellij IDEA的Bookmarks
    js中对小数取整
    idea 中pom.xml依赖版本号报错(报红,如下图所示)
    Springboot项目启动后访问不到Controller
    pringBoot Controller接收参数的几种常用方式
    Spring启动执行流程梳理
    SQL条件语句(IF, CASE WHEN, IF NULL)
    获取tomcat服务器上的部分日志
    Linux下 SpringBoot jar项目后台运行、查看、停用
  • 原文地址:https://www.cnblogs.com/lfri/p/11624935.html
Copyright © 2020-2023  润新知