• 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 }
  • 相关阅读:
    asp.net 数据导出到Excel
    系统架构之畅想
    access2003绿色中文版(转)
    项目那点事(共享)
    不错的消息提示
    配置Windows media service 流媒体服务器
    MemberShip 数据库的安装,web.config的配置及数据库文档结构
    windows server 2003 service pack 2 无法安装...产品密钥可能无效
    残忍,人
    js小技巧鼠标滑过显示大图
  • 原文地址:https://www.cnblogs.com/acgoto/p/9058529.html
Copyright © 2020-2023  润新知