zoukankan      html  css  js  c++  java
  • 【洛谷1290】欧几里德的游戏(博弈论)

    点此看题面

    大致题意: 给定两个正整数,从(Stan)开始,每次将两个数中较大的数减去较小数的正整数倍(得到数不能小于0),然后是(Ollie)进行同样操作。若谁先得到0谁就胜利,请你求出谁会取得胜利。

    分类讨论

    这一看就是博弈论题。

    我们可以用(w(x,y))来表示两个数分别为(x)(y)时的获胜情况(设(x≥y)),并设(a=lfloorfrac xy floor,b=x)%(y)

    下面是一波分类讨论:

    • 如果(x=y)

      显然此时的决策者胜利(可以直接将(x)减去(y),变成((y,0)))。

    • 如果(a≥2)

      • (w(y,b)=1)

        则此时的决策者必然可以使当前状态转移到((y+b,b))(只要将(x)减去(y(a-1))即可),然后对手就只能使状态转移到((y,b)),因此此时的决策者必胜。

      • (w(y,b)=0)

        则此时的决策者必然可以使当前状态转移到((y,b))(只要将(x)减去(ay)即可),则对手必输,因此此时的决策者必胜。

      综上所述,此时的决策者必胜。

    • 如果(a<2)

      这时,我们不能直接看出此时决策者是否必胜或必输,这时候就需要递归了,因为此时的决策只有一种(将(x)减去(y)),因此此时的获胜情况就是(!w(y,x-y))

    递归函数w(x,y)

    这样一来,就不难得出一个递归函数(w(x,y))了:

    inline bool w(int x,int y)//递归函数,判断两个数分别为x和y,且x≥y时是否必胜
    {
        if(x^y&&x/y<2) return !w(y,x-y);//如果x≠y且x/y<2,就不能直接看出必胜或必输,因此就执行此时唯一的决策方案,并递归调用w()函数
        return true;//否则,x=y或x/y≥2,通过上面的证明可得此时的决策者必胜
    }
    

    代码

    #include<bits/stdc++.h>
    #define max(x,y) ((x)>(y)?(x):(y))
    #define min(x,y) ((x)<(y)?(x):(y))
    #define abs(x) ((x)<0?-(x):(x))
    #define LL long long
    #define ull unsigned long long
    #define swap(x,y) (x^=y,y^=x,x^=y)
    #define tc() (A==B&&(B=(A=ff)+fread(ff,1,100000,stdin),A==B)?EOF:*A++)
    #define pc(ch) (pp_<100000?pp[pp_++]=ch:(fwrite(pp,1,100000,stdout),pp[(pp_=0)++]=ch))
    #define N 20
    int pp_=0;char ff[100000],*A=ff,*B=ff,pp[100000];
    using namespace std;
    int n,m;
    inline void read(int &x)
    {
        x=0;static char ch;
        while(!isdigit(ch=tc()));
        while(x=(x<<3)+(x<<1)+ch-48,isdigit(ch=tc()));
    }
    inline void ps(string x)
    {
        register int i,len=x.length();
        for(i=0;i<len;++i) pc(x[i]);
    }
    inline bool w(int x,int y)//递归函数w(x,y)
    {
        if(x^y&&x/y<2) return !w(y,x-y);
        return true;
    }
    int main()
    {
        register int i,T;read(T);
        while(T--)
        {
            read(n),read(m);
            w(max(n,m),min(n,m))?ps("Stan wins
    "):ps("Ollie wins
    ");
        }
        return fwrite(pp,1,pp_,stdout),0;
    }
    
  • 相关阅读:
    软件的安全性应从哪几个方面去测试?
    目前主要的测试用例设计方法是什么?
    什么是软件质量?
    软件配置管理的作用?软件配置包括什么?
    什么是软件测试?软件测试的目的与原则
    软件生存周期及其模型是什么?
    软件的概念和特点?软件复用的含义?构件包括哪些?
    一台客户端有三百个客户与三百个客户端有三百个客户对服务器施压,有什么区别?
    在搜索引擎中输入汉字就可以解析到对应的域名,请问如何用LoadRunner进行测试。
    测试08
  • 原文地址:https://www.cnblogs.com/chenxiaoran666/p/Luogu1290.html
Copyright © 2011-2022 走看看