poj Georgia and Bob + 蓝桥杯决赛原题:高僧斗法 阶梯博弈大法


Language: Default
Georgia and Bob
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 8812   Accepted: 2832

Description

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

思路:从右到左两两小球绑定,求6-7,1-3的间隔值并异或

点击打开链接


#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
int num[1010];
int main()
{
    int T;
    cin>>T;
    while(T--)
    {
        int n;
        cin>>n;
        for(int i=1;i<=n;i++)
            cin>>num[i];
        num[0]=0;
        sort(num,num+n+1);
        int ans=0;
        for(int i=n;i>0;i-=2)
            ans=ans^(num[i]-num[i-1]-1);
        if(ans==0)
            cout<<"Bob will win"<<endl;
        else
            cout<<"Georgia will win"<<endl;
    }
    return 0;
}


问题描述
  古时丧葬活动中经常请高僧做法事。仪式结束后,有时会有“高僧斗法”的趣味节目,以舒缓压抑的气氛。
  节目大略步骤为:先用粮食(一般是稻米)在地上“画”出若干级台阶(表示N级浮屠)。又有若干小和尚随机地“站”在某个台阶上。最高一级台阶必须站人,其它任意。(如图1所示)
  两位参加游戏的法师分别指挥某个小和尚向上走任意多级的台阶,但会被站在高级台阶上的小和尚阻挡,不能越过。两个小和尚也不能站在同一台阶,也不能向低级台阶移动。
  两法师轮流发出指令,最后所有小和尚必然会都挤在高段台阶,再也不能向上移动。轮到哪个法师指挥时无法继续移动,则游戏结束,该法师认输。
  对于已知的台阶数和小和尚的分布位置,请你计算先发指令的法师该如何决策才能保证胜出。
输入格式
  输入数据为一行用空格分开的N个整数,表示小和尚的位置。台阶序号从1算起,所以最后一个小和尚的位置即是台阶的总数。(N<100, 台阶总数<1000)
输出格式
  输出为一行用空格分开的两个整数: A B, 表示把A位置的小和尚移动到B位置。若有多个解,输出A值较小的解,若无解则输出-1。
样例输入
1 5 9
样例输出
1 4
样例输入
1 5 8 10
样例输出
1 3




#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int a[110];
int b[110];
int main()
{
    int n=0;
    while(cin>>a[n])
        n++;
    sort(a,a+n);
    for(int i=0;i<=n-2;i++)
        b[i]=a[i+1]-a[i]-1;
    int ans=0;
    for(int i=0;i<=n-2;i+=2)
        ans=ans^b[i];
    if(ans==0)
        cout<<"-1"<<endl;
    else
    {//<span style="font-family: Arial, Helvetica, sans-serif;">求必胜的时候第一步怎么走:枚举第i个棋子移动j步,使得剩下的局面异或等于0</span>

        for(int i=0;i<=n-2;i++)
            for(int j=1;a[i]+j<a[i+1];j++)
        {
            b[i]=b[i]-j;
            if(i>0)
                b[i-1]=b[i-1]+j;
            int sum=0;
            for(int i=0;i<=n-2;i+=2)
                sum=sum^b[i];
            if(sum==0)
            {
                cout<<a[i]<<" "<<a[i]+j<<endl;
                return 0;
            }
            b[i]=b[i]+j;
            if(i>0)
                b[i-1]=b[i-1]-j;
        }
    }
    return 0;
}


你可能感兴趣的:(尼姆博弈论,阶梯博弈)