博弈题目总结

第一题:Matches Game

Here is a simple game. In this game, there are several piles of matches and two players. The two player play in turn. In each turn, one can choose a pile and take away arbitrary number of matches from the pile (Of course the number of matches, which is taken away, cannot be zero and cannot be larger than the number of matches in the chosen pile). If after a player’s turn, there is no match left, the player is the winner. Suppose that the two players are all very clear. Your job is to tell whether the player who plays first can win the game or not.

Input

The input consists of several lines, and in each line there is a test case. At the beginning of a line, there is an integer M (1 <= M <=20), which is the number of piles. Then comes M positive integers, which are not larger than 10000000. These M integers represent the number of matches in each pile.

Output

For each test case, output "Yes" in a single line, if the player who play first will win, otherwise output "No".

Sample Input

2 45 45
3 3 6 9

Sample Output

No
Yes

 

题意:有两个人做游戏:n堆火柴,每个人轮流拿火柴,规定只能在选定的一堆里拿。如果先手胜输出YES,否则输出NO。

思路:这道题是简单的nim博弈类型(有多堆),所以根据公式求sg即可。

code:

 

#include <iostream>
using namespace std;
int main()
{
    int M,a,b;
    while(cin >> M)
    {
        int i;
        cin >> a;
        b=a;
        for(i=1;i<M;i++)
        {
            cin >> a ;
            b=b^a;
        }
        if(b)
        cout << "Yes" << endl ;
        else
        cout << "No" << endl ;
    }
    return 0;
}


第二题:Georgia and Bob

Georgia and Bob decide to play a self-invented game. They draw a row of grids on paper, number the grids from left to right by 1, 2, 3, ..., and place N chessmen on different grids, as shown in the following figure for example:

Georgia and Bob move the chessmen in turn. Every time a player will choose a chessman, and move it to the left without going over any other chessmen or across the left edge. The player can freely choose number of steps the chessman moves, with the constraint that the chessman must be moved at least ONE step and one grid can at most contains ONE single chessman. The player who cannot make a move loses the game.

Georgia always plays first since "Lady first". Suppose that Georgia and Bob both do their best in the game, i.e., if one of them knows a way to win the game, he or she will be able to carry it out.

Given the initial positions of the n chessmen, can you predict who will finally win the game?

Input

The first line of the input contains a single integer T (1 <= T <= 20), the number of test cases. Then T cases follow. Each test case contains two lines. The first line consists of one integer N (1 <= N <= 1000), indicating the number of chessmen. The second line contains N different integers P1, P2 ... Pn (1 <= Pi <= 10000), which are the initial positions of the n chessmen.

Output

For each test case, prints a single line, "Georgia will win", if Georgia will win the game; "Bob will win", if Bob will win the game; otherwise 'Not sure'.

Sample Input

2
3
1 2 3
8
1 5 6 7 9 12 14 17

Sample Output

Bob will win
Georgia will win

题意:有一个一排的方格,从左至右编号为1,2,3,……,n。在格子中放置那个棋子,两人开始游戏,一个人移动棋子只能向左移动。不能跨越棋子,不能超过边界。知道不能移动为止,两人交替移动。

思路:从右向左两个棋子为一组,因为移动一个棋子,那么他与右边的棋子的距离就会增大,所以两个为一组,就转化为了多堆去石子的游戏。移动一组中左边的棋子,那么另一个人就移动右边的相同距离,若移动右边的,就相当于减少了“一堆石子”的数量。就变成了nim博弈的原理。

code:

#include <iostream>
#include <stdio.h>
#include <cmath>
#include <algorithm>
using namespace std ;
int a[1111] ;
int main()
{
    int t , i , n ;
    int b;
    cin >> t ;
    while(t--)
    {
        b=0;
        cin >> n ;
        for(i = 0 ; i < n ; i ++)
            cin >> a[i] ;
        if(n % 2 != 0)
        a[n ++] = 0;
        sort(a , a+n) ;
        for(i = 0 ; i < n-1 ; i = i + 2)
        b  = b ^ (a[i + 1] - a[i] - 1) ;
        if(b == 0)
        cout << "Bob will win" << endl ;
        else
        cout << "Georgia will win" << endl ;
    }
    return 0;
}

第三题:Cutting Game

Urej loves to play various types of dull games. He usually asks other people to play with him. He says that playing those games can show his extraordinary wit. Recently Urej takes a great interest in a new game, and Erif Nezorf becomes the victim. To get away from suffering playing such a dull game, Erif Nezorf requests your help. The game uses a rectangular paper that consists of W*H grids. Two players cut the paper into two pieces of rectangular sections in turn. In each turn the player can cut either horizontally or vertically, keeping every grids unbroken. After N turns the paper will be broken into N+1 pieces, and in the later turn the players can choose any piece to cut. If one player cuts out a piece of paper with a single grid, he wins the game. If these two people are both quite clear, you should write a problem to tell whether the one who cut first can win or not.

Input

The input contains multiple test cases. Each test case contains only two integers W and H (2 <= W, H <= 200) in one line, which are the width and height of the original paper.

Output

For each test case, only one line should be printed. If the one who cut first can win the game, print "WIN", otherwise, print "LOSE".

Sample Input

2 2
3 2
4 2

Sample Output

LOSE
LOSE
WIN

题意:有一张n*m的方格纸,两人开始剪纸,知道谁剪出1*1的方格,谁就胜出。

思路:这道题还没有太懂。大概的思路就是用sg函数,下一个的sg值是上两个sg值得异或。一直向上推出答案。

还不是很懂,先保存下来。改日再看。

code:

#include <iostream>
#include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cstring>
using namespace std;
int sg[255][255] ;
int boyi(int x,int y)
{
    bool next[255];
    int i ;
    memset(next,0,sizeof(next));
    if(sg[x][y] != -1)
    return sg[x][y] ;
    for(i = 2 ; i <= x - i ; i ++)
    next[boyi(i , y) ^ boyi(x - i , y)] = 1 ;
    for(i = 2 ; i <= y - i ; i ++)
    next[boyi(x , i) ^ boyi(x , y - i)] = 1 ;
    for(i = 0;;i ++)
    {
        //cout << next[i] << endl;
        if(next[i] == 0)
        {
            sg[x][y] = i ;
            return i ;
        }
    }
}
int main()
{
    int m,n;
    memset(sg,-1,sizeof(sg));
    sg[2][2] = sg[2][3] = sg[3][2] = 0 ;
    while(cin >> n >> m)
    {
        if(boyi(n , m) == 0)
        cout << "LOSE" << endl ;
        else
        cout << "WIN" << endl ;
    }
    return 0;
}


第四题:Kiki's game

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!


 

题意:有个n*m的方格,在方格的右上角有一枚硬币。两人交替移动硬币,只能向左、向下或者向右。知道不能移动为止。

思路:模拟出前几组数据,找规律,发现当n和m都为奇数时,输出What a pity!。否则,Wonderful!

code:

#include <iostream>
#include <stdio.h>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;
int main()
{
    int m , n ;
    while(cin >> m >> n)
    {
        if(m == 0 && n == 0)
        break;
        if(m % 2 == 1 && n % 2 == 1)
        cout << "What a pity!" << endl ;
        else
        cout << "Wonderful!" << endl ;
    }
    return 0;
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值