1. 程式人生 > >HDU 3389 Game【Nim博弈變形】階梯博弈

HDU 3389 Game【Nim博弈變形】階梯博弈

Bob and Alice are playing a new game. There are n boxes which have been numbered from 1 to n. Each box is either empty or contains several cards. Bob and Alice move the cards in turn. In each turn the corresponding player should choose a non-empty box A and choose another box B that B<A && (A+B)%2=1 && (A+B)%3=0. Then, take an arbitrary number (but not zero) of cards from box A to box B. The last one who can do a legal move wins. Alice is the first player. Please predict who will win the game.

Input

The first line contains an integer T (T<=100) indicating the number of test cases. The first line of each test case contains an integer n (1<=n<=10000). The second line has n integers which will not be bigger than 100. The i-th integer indicates the number of cards in the i-th box.

Output

For each test case, print the case number and the winner's name in a single line. Follow the format of the sample output.

Sample Input

2
2
1 2
7
1 3 3 2 2 1 2

Sample Output

Case 1: Alice
Case 2: Bob

首先在紙上畫了一下轉移圖:

1 3 4號盒子是不能夠再轉移卡片到其他盒子中去了的,其他盒子中的卡片經過若干步的轉移最終也一定會轉移到1 3 4號盒子中去。

具體來說,n % 6 == 0 或 2 或 5的盒子,經過奇數步

轉移到1 3 4中去,其他的則須經過偶數步才能轉移過去。

 

下面來證明,所有卡片都在偶數步盒子中是必敗狀態

因為不論先手將偶數步的盒子中卡片移走了多少,後手一定可以把這些卡片再往前移動一個盒子,直到移到1 3 4中去為止。

 

對於只有一個盒子有卡片,而且這個盒子是奇數步盒子來說,先手必勝

很簡單,根據上面的結論,只要先手把這個奇數步盒子中所有卡片全部往下移一個盒子就好了。這樣就轉移到了先手必敗狀態。

 

整個遊戲可以看做若干個子游戲的和遊戲,偶數步盒子不予考慮,只考慮奇數步盒子中的卡片,這就相當於一個n堆石子的Nim遊戲。

在一個奇數步盒子中移走k張卡片,相當於在某一堆石子中取走k個石子。把所有石子取完相當於,所有的卡片都在偶數步的盒子裡面,而我們已經證明完這種狀態是必敗狀態了。

所以在程式碼中就只需要將奇數步盒子中的卡片數異或一下求個Nim和,就能判斷勝負了。

import java.util.*;
import java.math.*;

public class Main{
	static int maxn=(int)(1e5+10);

	public static void main(String[] args) {
		Scanner cin=new Scanner(System.in);
		int T=cin.nextInt();
		int ca=1;
		while((T--)!=0) {
			int n=cin.nextInt();
			int ret=0;
			for(int i=1;i<=n;i++) {
				int x=cin.nextInt();
				if(i%6==0||i%6==2||i%6==5)
				ret^=x;
			}
			System.out.print("Case "+ ca++ +": ");
			if(ret==0)	
				System.out.println("Bob");
			else
				System.out.println("Alice");
		}
		cin.close();
	}
}