• Euclid's Game (简单博弈)


    Euclid's Game

    题意:本题的题意大概是讲两位选手分别对两个数字a,b轮流进行如下操作:

    • 较大的数字-较小的数字*k(k>0,k为整数)。
    • 当其中一个数字为0时结束游戏。
      谁进行最后一步操作,谁就获胜。

    题解:这一题总的来说还是一道简单题,解题的过程大概可以分为一下几类情况:

      假设a>=b总是成立。

    • 当a==b(a%b==0)时,先手获胜;
    • 当a>=2*b时,可化为(a%b,b),当这个状态为获胜态的时候,先手获胜;当这个状态为必败态的时候,先手讲(a,b)化为(a%b+b,b)这个状态,这个时候为后手面对的是必败态,先手获胜。注意,作为参赛人员,先手肯定知道(a%b,b)是不是获胜态。
    • 当b<a<2*b的时候,只有一条路可走,将它化为(a%b,b),这个时候,我们轮流进行,看谁先走到以上两种获胜态即可。

    代码:

    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #define ll long long
    using namespace std;
    int main(){
        int a,b;
        while(cin>>a>>b&&(a+b)){
            if(a==b&&b==0){
                break;
            }
            if(a<b){
                swap(a,b);
            }
            if(a%b==0){
                cout<<"Stan wins"<<endl;
                continue;
            }
            if(a>=2*b){
                cout<<"Stan wins"<<endl;
                continue;
            }
            if(b<a&&a<2*b){
                int num=0;//记录次数
                while(1){
                    if(a%b==0||a>=2*b){
                        break;
                    }
                    a=a%b;
                    if(a<b){
                        swap(a,b);
                    }
                    num++;
                }
                if(num%2!=0){
                    cout<<"Ollie wins"<<endl;
                }else{
                    cout<<"Stan wins"<<endl;
                }
                continue;
            }
        }
        return 0;
    }

    个人感想:这道题是一个简单的博弈,我们只要紧紧抓住获胜态这个状态,应为排除获胜态,剩下的就是必败态,这应该算是一种博弈题目常用的分析方式。

  • 相关阅读:
    远程桌面连接win10问题解决
    为什么n各节点的的二叉链表中有n+1个空链域
    西门子Step7找不到有效授权的解决方法
    表达式树获取函数命名
    逆波兰表达式
    双向循环链表实践
    快速找到未知长度单链表的中间节点
    java的ArrayList(线性表)和LinkedList(双向链表)的深入学习
    23种设计模式中的访问者模式
    23种设计模式中的原型模式
  • 原文地址:https://www.cnblogs.com/blogxsc/p/12885289.html
Copyright © 2020-2023  润新知