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;
    }
  • 相关阅读:
    搭建一个免费的,无限流量的Bloggithub Pages和Jekyll入门
    通过扩展方法 链式方法 为MVC 3 视图添加验证
    让移动UI模式设计者获得灵感的10个有用的网站资源
    企业级应用架构(NHibernater+Spring.Net+MVC3)_V1.0
    把博客放在Github
    实例化需求—流程
    nginx+keepalievd,实现负载均衡和故障点切换。keepalived双机热备。
    古城钟楼
    从初步使用该控件到多维数据集控件PivotGridControl
    搜索引擎的评价
  • 原文地址:https://www.cnblogs.com/lfri/p/11624935.html
Copyright © 2011-2022 走看看