zoukankan      html  css  js  c++  java
  • HDU3032 Nim or not Nim?(博弈/Multi-SG游戏)

    Problem Description

    Nim is a two-player mathematic game of strategy in which players take turns removing objects from distinct heaps. On each turn, a player must remove at least one object, and may remove any number of objects provided they all come from the same heap.

    Nim is usually played as a misere game, in which the player to take the last object loses. Nim can also be played as a normal play game, which means that the person who makes the last move (i.e., who takes the last object) wins. This is called normal play because most games follow this convention, even though Nim usually does not.

    Alice and Bob is tired of playing Nim under the standard rule, so they make a difference by also allowing the player to separate one of the heaps into two smaller ones. That is, each turn the player may either remove any number of objects from a heap or separate a heap into two smaller ones, and the one who takes the last object wins.

    Input

    Input contains multiple test cases. The first line is an integer 1 ≤ T ≤ 100, the number of test cases. Each case begins with an integer N, indicating the number of the heaps, the next line contains N integers s[0], s[1], ...., s[N-1], representing heaps with s[0], s[1], ..., s[N-1] objects respectively.(1 ≤ N ≤ 10^6, 1 ≤ S[i] ≤ 2^31 - 1)

    Output

    For each test case, output a line which contains either "Alice" or "Bob", which is the winner of this game. Alice will play first. You may asume they never make mistakes.

    Sample Input

    2
    3
    2 2 3
    2
    3 3
    

    Sample Output

    Alice
    Bob
    

    Multi-SG游戏模版(可以将一堆石子分成多堆,此题为两堆)。求解方法是先打表找规律,然后直接异或判断。

    详细证明:HDU3032_NimOrNotNim解题报告_weixin_30865427的博客-CSDN博客

    打表代码及ac代码如下:

    #include <bits/stdc++.h>
    #define N 5005
    using namespace std;
    int n, a[1000005];
    int sg[100005];
    bool vis[100005];
    void dabiao() {
    	sg[0] = 0, sg[1] = 1;
    	for(int i = 1; i < N; i++) {
    		memset(vis, 0, sizeof(vis));
    		//操作1:至少取一个 最多全取走
    		for(int j = 1; j <= i; j++) {vis[sg[i - j]] = 1;}
    		//注意这里要取等
    		//操作2:分成两堆,因为一堆不能为空所以不能取等
    		//将一堆石子分成两堆,等于将一个一堆的Nim游戏A变成两个一堆游戏的和B,这两个一堆游戏之和也是A的后继状态。计算A的SG函数时,除了考虑普通后继状态之外,还要将B的SG值加入mex计算,而B的SG值是两个成员游戏SG值的异或◎(根据和游戏定理)。
    		for(int j = 1; j < i; j++) {vis[sg[j] ^ sg[i - j]] = 1;}
    		for(int k = 0; k < N; k++) {//mex操作 该状态的 SG 函数值即为后继状态的 SG 函数值中未出现过的最小值
    			if(!vis[k]) {
    				sg[i] = k;
    				break;
    			}
    		}
    		cout << sg[i] << endl;
    	}
    }
    int getSG(int x) {
    	if(x % 4 == 0) return x - 1;
    	else if(x % 4 == 3) return x + 1;
    	else return x;
    }
    int main() { 
    	int t;
    	cin >> t;
    	while(t--) {
    		cin >> n;
    		int x = 0;
    		for(int i = 1; i <= n; i++) {
    			int tmp;
    			cin >> tmp;
    			x ^= getSG(tmp);
    		}
    		if(x) cout << "Alice" << endl;
    		else cout << "Bob" << endl;
    	}
    	return 0;
    }
    
  • 相关阅读:
    预编译
    AndroidRuntime: android.app.RemoteServiceException: Bad notification posted from package
    RadioButton和RadioGroup一点使用心得
    POJ 2774 Long Long Message 后缀数组
    POJ 2406 Power String 后缀数组
    URAL 1297 Palindrome 后缀数组+RMQ
    SPOJ 694 705 后缀数组
    POJ 3261 Milk Patterns 后缀数组
    POJ 1743 Musical Theme 后缀数组
    HDU 5040 Instrusive BFS
  • 原文地址:https://www.cnblogs.com/lipoicyclic/p/14730644.html
Copyright © 2011-2022 走看看