zoukankan      html  css  js  c++  java
  • P1290 欧几里德的游戏

    原题链接  https://www.luogu.com.cn/problem/P1290

     

    题解

    模拟赛的一道题,我大眼一看是博弈论的题,想都没想直接跳过(我完全不会博弈论),看了题解之后发现其实并不难;

    直接看结论:

    记当前状态为 $d(x,y)$ ,且 $x>y$ ,若此时 $x >= 2y$  ,则目前的操作者胜利;

    下面是证明:

    假定 $x=ky+r$,其中 $r = x \% y$,$k = x / y$ ,根据假设,$k>=2$,此时讨论 $d(y,r)$ 的可能情况:

    $1$. 若 $d(y,r)$ 为必胜状态(即当时的操作者有必胜策略),则当前操作者( 即 $d(y,r)$ 状态下的操作者 )可以转移到 $d(y+r,r)$(取 $k-1$ 堆小的,由于 $k>=2$,肯定可以取到 )。

    此时,轮到对手操作。因为必须要取正整数堆较小的,所以只能转移到 $d(y,r)$ 这个必胜状态上。那么,当前的操作者胜利。

    若 $d(y,r)$ 为必败状态,其实是类似的,可以直接转移从 $d(x,y)$ 至 $d(y,r)$,把必败状态留给后手。

    这样,就能把必败状态留给对手,将必胜状态留给自己,那么自己必胜!

    这样的话,我们在搜索的时候如果出现 $x >= 2y$ 的情况,则当前的操作者必胜,否则转移到 $d ( x , x - y )$ ;

    $Code$:

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    int dfs(int x,int y,int p) //p表示当前的操作者,0是先手的人,1是后手的人 
    {
        if(x==y) return p;     //当x==y,那么当前操作者必胜 
        if(x>=2*y) return p;   //结论 
        else return dfs(y,x-y,p^1);
    }
    int n,m,T;
    int main()
    {
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d%d",&n,&m);
            if(n<m) swap(n,m);      //保证让第一个是较大的数 
            if(dfs(n,m,1)==0) printf("Ollie wins
    ");  
            else printf("Stan wins
    ");
        }
    }
  • 相关阅读:
    python【第五篇】常用模块学习
    (三)训练HMM模块
    (二)杂项准备
    (四)看看成果
    (一)准备训练语音文件
    HTK语音识别示例(Ubuntu)
    RoboCup仿真3D TC笔记(2014年合肥中国公开赛 仿真3D比赛环境搭建)
    WebFont与页面font-icon图标研究
    Font Awesome使用方法
    css sprites拼合
  • 原文地址:https://www.cnblogs.com/xcg123/p/12913026.html
Copyright © 2011-2022 走看看