zoukankan      html  css  js  c++  java
  • 巴什博弈

    巴什博弈

      问题模型:只有一堆n个物品,两个人轮流从这堆物品中取物,规定每次至少取一个,最多取m个,最后取关者获胜。

      思路:当n=m+1时,由于最多取m个,最少取1个,所以先手无论取多少个,都输,即先手必输状态。所以但面临 n%(m+1) = 0 得到状态是,必输。而当是n = k(m+1) + s时,先手只需拿s个就可以让后手面临必输状态,即先手比胜状态。

    下面贴几个相关的题目:

    HDU2188:

    对于四川同胞遭受的灾难,全国人民纷纷伸出援助之手,几乎每个省市都派出了大量的救援人员,这其中包括抢险救灾的武警部队,治疗和防疫的医护人员,以及进行心理疏导的心理学专家。根据要求,我校也有一个奔赴灾区救灾的名额,由于广大师生报名踊跃,学校不得不进行选拔来决定最后的人选。经过多轮的考核,形势逐渐明朗,最后的名额将在“林队”和“徐队”之间产生。但是很巧合,2个人的简历几乎一模一样,这让主持选拔的8600很是为难。无奈,他决定通过捐款来决定两人谁能入选。
    选拔规则如下:
    1、最初的捐款箱是空的;
    2、两人轮流捐款,每次捐款额必须为正整数,并且每人每次捐款最多不超过m元(1<=m<=10)。
    3、最先使得总捐款额达到或者超过n元(0<n<10000)的一方为胜者,则其可以亲赴灾区服务。
    我们知道,两人都很想入选志愿者名单,并且都是非常聪明的人,假设林队先捐,请你判断谁能入选最后的名单?
     
    Input
    输入数据首先包含一个正整数C,表示包含C组测试用例,然后是C行数据,每行包含两个正整数n,m,n和m的含义参见上面提到的规则。
     
    Output
    对于每组测试数据,如果林队能入选,请输出字符串"Grass", 如果徐队能入选,请输出字符串"Rabbit",每个实例的输出占一行。
     

    Sample Input

    2
    8 10
    11 10
     

    Sample Output

    Grass
    Rabbit
     1 #include <iostream>
     2 using namespace std;
     3 int main(){
     4     int c, n, m;
     5     cin >> c;
     6     while(c--){
     7         cin >> n >> m;
     8         if(n%(m+1)) cout << "Grass" << endl;
     9         else cout << "Rabbit" << endl;
    10     }
    11     return 0;
    12 }
    View Code

    HDU2149

    虽然不想,但是现实总归是现实,Lele始终没有逃过退学的命运,因为他没有拿到奖学金。现在等待他的,就是像FarmJohn一样的农田生涯。

    要种田得有田才行,Lele听说街上正在举行一场别开生面的拍卖会,拍卖的物品正好就是一块20亩的田地。于是,Lele带上他的全部积蓄,冲往拍卖会。

    后来发现,整个拍卖会只有Lele和他的死对头Yueyue。

    通过打听,Lele知道这场拍卖的规则是这样的:刚开始底价为0,两个人轮流开始加价,不过每次加价的幅度要在1~N之间,当价格大于或等于田地的成本价 M 时,主办方就把这块田地卖给这次叫价的人。

    Lele和Yueyue虽然考试不行,但是对拍卖却十分精通,而且他们两个人都十分想得到这块田地。所以他们每次都是选对自己最有利的方式进行加价。

    由于Lele字典序比Yueyue靠前,所以每次都是由Lele先开始加价,请问,第一次加价的时候,
    Lele要出多少才能保证自己买得到这块地呢?
     
    Input
    本题目包含多组测试,请处理到文件结束(EOF)。每组测试占一行。
    每组测试包含两个整数M和N(含义见题目描述,0<N,M<1100)
     
    Output
    对于每组数据,在一行里按递增的顺序输出Lele第一次可以加的价。两个数据之间用空格隔开。
    如果Lele在第一次无论如何出价都无法买到这块土地,就输出"none"。
     
    Sample Input
    4 2
    3 2
    3 5
     
    Sample Output
    1
    none
    3 4 5
     1 #include <iostream>
     2 using namespace std;
     3 int main(){
     4     int n, m;
     5     while(cin>>m>>n){
     6         if(m%(n+1) == 0) cout << "none
    ";
     7         else{
     8             if(m <= n){
     9                 for(int i = m; i < n; i++){
    10                     cout << i << ' ';
    11                 }
    12                 cout << n << endl;
    13             }
    14             else cout << m%(n+1) << endl;
    15         }
    16     }
    17     return 0;
    18 }
    View Code

    HDU1847

    大学英语四级考试就要来临了,你是不是在紧张的复习?也许紧张得连短学期的ACM都没工夫练习了,反正我知道的Kiki和Cici都是如此。当然,作为在考场浸润了十几载的当代大学生,Kiki和Cici更懂得考前的放松,所谓“张弛有道”就是这个意思。这不,Kiki和Cici在每天晚上休息之前都要玩一会儿扑克牌以放松神经。
    “升级”?“双扣”?“红五”?还是“斗地主”?
    当然都不是!那多俗啊~
    作为计算机学院的学生,Kiki和Cici打牌的时候可没忘记专业,她们打牌的规则是这样的:
    1、  总共n张牌;
    2、  双方轮流抓牌;
    3、  每人每次抓牌的个数只能是2的幂次(即:1,2,4,8,16…)
    4、  抓完牌,胜负结果也出来了:最后抓完牌的人为胜者;
    假设Kiki和Cici都是足够聪明(其实不用假设,哪有不聪明的学生~),并且每次都是Kiki先抓牌,请问谁能赢呢?
    当然,打牌无论谁赢都问题不大,重要的是马上到来的CET-4能有好的状态。

    Good luck in CET-4 everybody!
     

    Input

    输入数据包含多个测试用例,每个测试用例占一行,包含一个整数n(1<=n<=1000)。
     

    Output

    如果Kiki能赢的话,请输出“Kiki”,否则请输出“Cici”,每个实例的输出占一行。
     

    Sample Input

    1
    3
     

    Sample Output

    Kiki
    Cici
     1 #include <iostream>
     2 #include <cstdio>
     3 using namespace std;
     4 
     5 int main(){
     6     int n;
     7     while(cin >> n){
     8         if(n%3)cout << "Kiki
    ";
     9         else cout << "Cici
    ";
    10     }
    11     return 0;
    12 }
    View Code

    HDU1846

    十年前读大学的时候,中国每年都要从国外引进一些电影大片,其中有一部电影就叫《勇敢者的游戏》(英文名称:Zathura),一直到现在,我依然对于电影中的部分电脑特技印象深刻。
    今天,大家选择上机考试,就是一种勇敢(brave)的选择;这个短学期,我们讲的是博弈(game)专题;所以,大家现在玩的也是“勇敢者的游戏”,这也是我命名这个题目的原因。
    当然,除了“勇敢”,我还希望看到“诚信”,无论考试成绩如何,希望看到的都是一个真实的结果,我也相信大家一定能做到的~

    各位勇敢者要玩的第一个游戏是什么呢?很简单,它是这样定义的:
    1、  本游戏是一个二人游戏;
    2、  有一堆石子一共有n个;
    3、  两人轮流进行;
    4、  每走一步可以取走1…m个石子;
    5、  最先取光石子的一方为胜;

    如果游戏的双方使用的都是最优策略,请输出哪个人能赢。
     

    Input

    输入数据首先包含一个正整数C(C<=100),表示有C组测试数据。
    每组测试数据占一行,包含两个整数n和m(1<=n,m<=1000),n和m的含义见题目描述。
     
    Output
    如果先走的人能赢,请输出“first”,否则请输出“second”,每个实例的输出占一行。
     
    Sample Input
    2
    23 2
    4 3
     
    Sample Output
    first
    second
     1 #include <iostream>
     2 #include <cstdio>
     3 using namespace std;
     4 
     5 int main(){
     6     int n, m ,c;
     7     cin >>c;
     8     while(c--){
     9         cin >> n >> m;
    10         if(n%(m+1))cout << "first
    ";
    11         else cout << "second
    ";
    12     }
    13     return 0;
    14 }
    View Code

    HDU2147

    Problem Description
    Recently kiki has nothing to do. While she is bored, an idea appears in his mind, she just playes the checkerboard game.The size of the chesserboard is n*m.First of all, a coin is placed in the top right corner(1,m). Each time one people can move the coin into the left, the underneath or the left-underneath blank space.The person who can't make a move will lose the game. kiki plays it with ZZ.The game always starts with kiki. If both play perfectly, who will win the game?
     
    Input
    Input contains multiple test cases. Each line contains two integer n, m (0<n,m<=2000). The input is terminated when n=0 and m=0.

     Output
    If kiki wins the game printf "Wonderful!", else "What a pity!".
     
    Sample Input
    5 3
    5 4
    6 6
    0 0
     
    Sample Output
    What a pity!
    Wonderful!
    Wonderful!
     1 #include <iostream>
     2 #include <cstdio>
     3 using namespace std;
     4 
     5 int main(){
     6     int n, m;
     7     while(cin >> n >> m){
     8         if(n == 0 && m == 0)break;
     9         if(n%2&&m%2)cout << "What a pity!
    ";
    10         else cout << "Wonderful!
    ";
    11     }
    12     return 0;
    13 }
    View Code

    HDU3863

    One day, Flyvan introduced a new game to his two friends, Oregon Maple and Grape Skin. The game is quite simple. Given an N-sized grids, like the figure A shown below (as N = 4). The blue points are the places the first player can choose, and the red points are the places the second player can choose.

    In the game, the two players take turns to choose two points to get connected by a stick. The two chosen points’ distance should be exactly one-unit length. The first player’s goal is to create a ‘bridge’ that connects a most left point and a most right point. The second player’s goal is to create a ‘bridge’ that connects a most top point and a most bottom point. Figure B shows a possible result (the first player won). In addition, the stick shouldn’t get crossed.
    Now Flyvan will give the number N, and his two friends will play the game. Both of the two players will choose the best strategy. You can bet on one player, and if he wins the game, you’ll get twice money you bet~
    Since you are a talented programmer, you surely won’t just do gambling. Please write a program to find out the player who you should bet on. As Oregon Maple is elder, he will always play first.
     
    Input
    Each line of the input is an integer N (2 <= N <= 270000), which indicated the number Flyvan chose. The end-of-file is denoted by a single line containing the number -1.
     
    Output
    If you think the first player will win, please output “I bet on Oregon Maple~”, else please output “I bet on Grape Skin~”.
     
    Sample Input
    2
    -1
     
    Sample Output
    I bet on Oregon Maple~
     1 #include <iostream>
     2 #include <cstring>
     3 #include <cstdio>
     4 using namespace std;
     5 
     6 int main(){
     7     int n;
     8     while(cin>>n){
     9         if(n == -1)break;
    10         puts("I bet on Oregon Maple~");
    11     }
    12 }
    View Code

    HDU1517

    Stan and Ollie play the game of multiplication by multiplying an integer p by one of the numbers 2 to 9. Stan always starts with p = 1, does his multiplication, then Ollie multiplies the number, then Stan and so on. Before a game starts, they draw an integer 1 < n < 4294967295 and the winner is who first reaches p >= n.
     
    Input
    Each line of input contains one integer number n.
     
    Output
    For each line of input output one line either Stan wins. or Ollie wins.assuming that both of them play perfectly.
     
    Sample Input
    162
    17
    34012226
     
    Sample Output
    Stan wins.
    Ollie wins.
    Stan wins.
     
     1 #include <iostream>
     2 #include <cstdio>
     3 #define ll long long
     4 using namespace std;
     5 
     6 int main(){
     7     ll n;
     8     while(cin>>n){
     9         ll ans = 1,sum;
    10         for(int i = 1;;i++){
    11             if(i&1) ans*=9;
    12             else ans*=2;
    13             if(ans>=n){
    14                 sum = i;
    15                 break;
    16             }
    17         }
    18         if(sum%2==0)puts("Ollie wins.");
    19         else puts("Stan wins.");
    20     }
    21 }
    View Code
  • 相关阅读:
    Android的目录结构说明
    IOS-线程(GCD)
    iOS UI-线程(NSThread)及其安全隐患与通信
    iOS UI-自动布局(AutoLayout)
    iOS UI-自动布局(Autoresizing)
    IOS-Core Data的使用
    OC 数据持久化(数据本地化)- 本地存储
    iOS UI-应用管理(使用Cell模板)
    IOS UI-QQ好友列表
    IOS-多线程
  • 原文地址:https://www.cnblogs.com/xingkongyihao/p/6665512.html
Copyright © 2011-2022 走看看