hdu 3032 Nim or not Nim?

Topic meaning:

Alice and Bob take turns to take N piles of stones, each pile is S[i], Alice first, each time can take any stone from any pile, or can divide a pile of stones into two small piles. The first to finish wins. (1 ≤ N ≤ 10^6, 1 ≤ S[i] ≤ 2^31 - 1)

Problem solving ideas:

For a given directed acyclic graph, define the Sprague-Grundy function g about each vertex of the graph as follows: g(x)=mex{ g(y) | y is the successor of x}, where g(x ) is sg[x]
For example, in the problem of taking stones, there is a pile of n stones, and only {1, 3, 4} stones can be taken at a time. The one who takes the stones first wins, then what is the SG value of each number?
When sg[0]=0,
n=1, {1} stones can be removed, leaving {0} stones, mex{sg[0]}={0}, so sg[1]=1;
n=2 When , {1} stones can be taken away, the remaining {1} stones, mex{sg[1]}={1}, so sg[2]=0;
when n=3, {1,3} can be taken away There are {2,0} stones remaining, mex{sg[2],sg[0]}={0,0}, so sg[3]=1;
when n=4, {1,3 can be taken away ,4} stones, {3,1,0} remaining, mex{sg[3],sg[1],sg[0]}={1,1,0}, so sg[4]=2;
When n=5, {1,3,4} stones can be taken away, and the remaining {4,2,1} stones, mex{sg[4],sg[2],sg[1]}={2,0 ,1}, so sg[5]=3;
and so on.....
     x 0 1 2 3 4 5 6 7 8....
sg[x] 0 1 0 1 2 3 2 0 1... .

So, for this question:

sg[0]=0

sg[1]=mex{sg[0] }=1

sg[2]=mex{sg[0],sg[1],sg[1,1] }=mex{0,1,1^1}=2;

sg[3]=mex{sg[0],sg[1],sg[2],sg[1,2]}=mex{0,1,2,1^2}=mex{0,1,2 ,3}=4;

sg[4]=mex{sg[0],sg[1],sg[2],sg[3],sg[1,3],sg[2,2]}=mex{0,1,2, 4,5,0}=3;

              ..............................................................................

It can be found: sg[4*k+1]=4*k+1,sg[4*k+2]=4*k+2, sg[4*k+3]=4*k+4,sg[ 4*k+4]=4*k+3

sg function table program

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
int main() {
	int i, j;
	int sg[1010], mex[1010];
	sg [0] = 0, sg [1] = 1;
	for(i = 2; i <= 1000; i++) {
		memset(mex, 0, sizeof mex);
		for(j = 1; j <= i/2; j++) {
			mex[sg[j]^sg[i - j]] = 1;
		}
		for(j = 1; j <= i; j++) {
			mex[sg[i - j]] = 1;
		}
		for(j = 0; ; j++) {
			if(mex[j] == 0) {
				sg[i] = j;
				break;
			}
		}
	}
	for(i = 0; i <= 100; i++) {
		printf("sg[%d] : %d\n", i, sg[i]);
	}
	return 0;
}

#include<stdio.h>
using namespace std;

int sg(int x){
	if(x%4==0)
	return x-1;
	if(x%4==3)
	return x+1;
	else return x;
}
int main(){
	
	int t;
	scanf("%d",&t);
	while(t--){
		int n;
		scanf("%d",&n);
		int temp=0;
		for(int i=0;i<n;i++)
		{
			int x;
			scanf("%d",&x);
			temp^=sg(x);
		}
		if(temp)
		printf("Alice\n");
		else printf("Bob\n");
	}
	
	return 0;
}


Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325778121&siteId=291194637