zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    rabbitmq在linux下单节点部署和基本使用
    使用kafka-python客户端进行kafka kerberos认证
    python confluent kafka客户端配置kerberos认证
    linux下rocksdb的编译安装
    linux下gflags的安装
    ASP.NET:/WebResource.axd
    公司-IT-信息安全:江南天安
    信息安全-证书:数字证书
    信息安全-证书-数字证书:SSL证书
    Error-DotNet:无法为目标平台“Microsoft.Data.Tools.Schema.Sql.Sql120DatabaseSechemaProvider”创建扩展管理器
  • 原文地址:https://www.cnblogs.com/lfri/p/11624935.html
Copyright © 2011-2022 走看看