POJ题目1704(Staircase Nim(阶梯博弈))

Georgia and Bob
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 7605   Accepted: 2317

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

Source

POJ Monthly--2004.07.18
首先先讲讲阶梯nim博弈(转自 http://blog.csdn.net/kk303/article/details/6692506 )
首先是对阶梯博弈的阐述...博弈在一列阶梯上进行...每个阶梯上放着自然数个点..两个人进行阶梯博弈...每一步则是将一个集体上的若干个点( >=1 )移到前面去..最后没有点可以移动的人输..


如这就是一个阶梯博弈的初始状态 2 1 3 2 4 ... 只能把后面的点往前面放...如何来分析这个问题呢...其实阶梯博弈经过转换可以变为Nim..把所有奇数阶梯看成N堆石子..做nim..把石子从奇数堆移动到偶数堆可以理解为拿走石子..就相当于几个奇数堆的石子在做Nim..( 如所给样例..2^3^4=5 不为零所以先手必败)为什么可以这样来转化?
   假设我们是先手...所给的阶梯石子状态的奇数堆做Nim先手能必胜...我就按照能赢的步骤将奇数堆的石子移动到偶数堆...如果对手也是移动奇数堆..我们继续移动奇数堆..如果对手将偶数堆的石子移动到了奇数堆..那么我们紧接着将对手所移动的这么多石子从那个奇数堆移动到下面的偶数堆...两次操作后...相当于偶数堆的石子向下移动了几个..而奇数堆依然是原来的样子...即为必胜的状态...就算后手一直在移动偶数堆的石子到奇数堆..我们就一直跟着他将石子继续往下移..保持奇数堆不变...如此做下去..我可以跟着后手把偶数堆的石子移动到0..然后你就不能移动这些石子了...所以整个过程..将偶数堆移动到奇数堆不会影响奇数堆做Nim博弈的过程..整个过程可以抽象为奇数堆的Nim博弈...
   其他的情况...先手必输的...类似推理...只要判断奇数堆做Nim博弈的情况即可...
   为什么是只对奇数堆做Nim就可以...而不是偶数堆呢?...因为如果是对偶数堆做Nim...对手移动奇数堆的石子到偶数堆..我们跟着移动这些石子到下一个奇数堆...那么最后是对手把这些石子移动到了0..我们不能继续跟着移动...就只能去破坏原有的Nim而导致胜负关系的不确定...所以只要对奇数堆做Nim判断即可知道胜负情况...
 
题目大意:
每个测试点最多有T(1 <= T <= 20)个测试数据。如图所示,Georgia和Bob在玩一种自创的游戏。一个无限长的棋盘上有N个旗子(1 <= N <= 1000),第i个棋子的位置可以用Pi表示(1 <= Pi <= 10000)。现在Georgia先走。每个人每一次可以把一枚棋子向左移动任意个格子,但是不能超越其他棋子,也不能和其他棋子处在同一个格子里。如果轮到某一个人的时候Ta再也不能移动棋子了,就判负。现在每个测试数据给定一种情况,如果Georgia会赢,输出“Georgia will win”,如果Bob会赢,输出“Bob will win”,如果不确定,输出“Not sure”。两个人都知道获胜策略是什么,也会想方设法取得胜利。
思路:
以第二个样例为例:

1 5 6 7 9 12 14 17

第一个棋子不能向左移动了。第二个棋子可以向左移动3个格子。第三个棋子也不能移动了,以此类推,可以得到这样一个数列:

0 3 0 0 1 2 1 2,第n个数字代表第n个棋子可以移动的步数。

考虑一下把第二个棋子向左移动一格的情况,原数列变为:

0 2 1 0 1 2 1 2

这不就是把“第二堆”石子移了一个到右边的“第三堆”石子么?由此可以给出等价的游戏新定义:

给定N堆石子,每堆里面的石子个数都是非负的。每次可以把第i堆中的任意颗石子移动到第i + 1堆中(1 <= i < N),或者第N堆的石子扔掉任意颗。如果某人不能继续操作则判负。

ac代码
#include
#include
int cmp(const void *a,const void *b)
{
	return *(int *)a-*(int *)b;
}
int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		int n,a[100000],i,b[100000],s=0;
		scanf("%d",&n);
		for(i=0;i=0;i-=2)//从n-1到0,依次减2,取异或,因为他是向右移的,所以从右边看阶梯nim博弈,异或奇数位
			s^=b[i];
		if(s)
			printf("Georgia will win\n");
		else
			printf("Bob will win\n");
	}
}

你可能感兴趣的:(博弈,技巧)