• goj 小游戏(棋盘博弈)


    Problem Description:

    最近kiki无事可做,于是他想玩棋盘游戏。棋盘的大小是n * m。首先,棋子放置在右上角(1,m)。 每次可以将棋子向左方,下方或左下方移动一个位置。当移动到(n,1)时就无法移动,无法移动的人失败。 kiki和bibi一起玩。游戏总是从kiki开始。 如果两者都完美发挥,谁会赢得比赛?

    Input:

    输入包含多个测试用例。 每行包含两个整数n,m(0 <n,m <= 2000)。 当n = 0和m = 0时输入终。

    Output:

    如果kiki赢,输出kiki;如果bibi赢,输出bibi。

    Sample Input:

    5 3
    5 4
    6 6
    0 0
    

    Sample Output:

    bibi
    kiki
    kiki
    解题思路:这道题比赛的时候推算了半天(QAQ表示当时还没学到博弈)才发现只要给出的n*m的结果是奇数则后手(bibi)就胜利,否则(偶数)先手(kiki)胜利。
    证明:贴一张P/N图关于先手的输赢状态:

    说明:状态P:先手只要最后是状态P,即此时无法再移动,则后手必赢,先手必输。

    状态N:先手只要最后是状态N,后手就无法再移动,即先手必赢,后手必输。

    现在关于P,N的求解有三个规则(前提:两者移动的每一步都保证是最优策略)

    (1):最终态都是P

    (2):按照游戏规则,到达当前态的前态都是N的话,当前态是P

    (3):按照游戏规则,到达当前态的前态至少有一个P的话,当前态是N

    综上,通过P/N图的分布规律,可以得出结论:如果n*m是偶数,则先手必赢,否则后手必赢。
    AC代码:
     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 int main(){
     4     int n,m;
     5     while(cin>>n>>m && (m+n)){
     6         if(m*n%2==0)cout<<"kiki"<<endl;//只要n*m为偶数,则先手必赢
     7         else cout<<"bibi"<<endl;//否则后手必赢
     8     }
     9     return 0;
    10 }

     杭电hdu2147和此题几乎完全一样,只是输出不一样而已。题目链接:hdu 2147 kiki's game

     AC代码:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 int main()
     4 {
     5     int n,m;
     6     while(cin>>n>>m && (m+n)){
     7         if(m*n%2)cout<<"What a pity!"<<endl;//先手必输
     8         else cout<<"Wonderful!"<<endl;//先手必赢
     9     }
    10     return 0;
    11 }
  • 相关阅读:
    Day3学习笔记
    Day2学习笔记
    Day1学习笔记
    中文标识
    about original idea
    那些和matlab有关的
    GRE Sub math 报名
    虽然实际没有什么用,但是可能会有理论上的意义吧
    latex相关
    对venturelli theorem的重新认识
  • 原文地址:https://www.cnblogs.com/acgoto/p/9058529.html
Copyright © 2020-2023  润新知