A Simple Nim (Game----Multi-SG playing the table to find the rules)

Problem Description
Two players take turns picking candies from n heaps,the player who picks the last one will win the game.On each turn they can pick any number of candies which come from the same heap(picking no candy is not allowed).To make the game more interesting,players can separate one heap into three smaller heaps(no empty heaps)instead of the picking operation.Please find out which player will win the game if each of them never make mistakes.
 

Input
Intput contains multiple test cases. The first line is an integer  1T100 , 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[n1] , representing heaps with  s[0],s[1],...,s[n1]  objects respectively. (1n106,1s[i]109)
 

Output
For each test case,output a line whick contains either"First player wins."or"Second player wins".
 

Sample Input
 
  
224 431 2 4
 

Sample Output
 
  
Second player wins.First player wins.
 

The meaning of the title: a pile of candy and two people take turns to operate

1, take any candy in the pile

2. Divide a pile of candies into three piles (each pile is not empty)

Divided into three piles can be divided in this way, or other operations as long as the sum can be equal to the number

	for(int j = 1 ; j <= i ; j++)//divide into three piles
		{
			for(int k = 1 ; k <= i ; k++)
			{
				for(int o = 1 ; o <= i ; o++)
				{
					if(j + k + o == i)
					{
						Hash [sg [j] ^ sg [k] ^ sg [o]] = 1;
					}
				}
			}
		 }

Just find a rule by typing the table, and then write according to the rule, so the time complexity is not considered here.

SG meter code:

int sg[maxn] , Hash[maxn];
void getsg(int x)
{
	memset(sg , 0 , sizeof(sg));
	for(int i = 0 ; i <= x ; i++)
	{
		memset(Hash , 0 , sizeof(Hash));
		for(int j = 1 ; j <= i ; j++)
		{
			Hash[sg[ij]] = 1;//Take any number
		}
		for(int j = 1 ; j <= i ; j++)//divide into three piles
		{
			for(int k = 1 ; k <= i ; k++)
			{
				for(int o = 1 ; o <= i ; o++)
				{
					if(j + k + o == i)
					{
						Hash [sg [j] ^ sg [k] ^ sg [o]] = 1;
					}
				}
			}
		 }
		 for(int j = 0 ; j<= x ; j++)
		 {
		 	if(Hash[j] == 0)
		 	{
		 		sg[i] = j;
		 		break;
			 }
		 }
		 cout << i << ":" << sg[i] << endl;
	}
}

Thereby discovering the law;

When x%8 == 0, sg[x] = x-1;

When x%8 == 7, sg[x] = x+1;

So the code is as follows:

#include <stdio.h>
#include <iostream>
#include <cstring>
using namespace std;
intmain()
{
	int n , t , x , flag;
	while(~scanf("%d" , &n))
	{
		while(n--)
		{
			 flag = 0 ;
			scanf("%d" , &t);
			while(t--)
			{
				scanf("%d" , &x);
				if(x % 8 == 0)
				{
					flag ^= x-1;
				}
				else if(x%8 == 7)
				{
					flag ^= x+1;
				 }
				 else
				 {
				 	flag ^= x;
				 }
			
			}
			if(flag == 0)
			{
				printf("Second player wins.\n");
			}
			else
			{
				printf("First player wins.\n");
			}
		}
	}
	return 0;
 }

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326746676&siteId=291194637