First defines the MEX (minimal excludant) operation, which is an operation exerted on a set, representing the smallest nonnegative integer that does not belong to this set. For example
Mex{0,1,2,4}=3, Mex{2,3,5}=0, mex{}=0.
For a given direction-free graph, the sprague-grundy function for each vertex of the graph is defined as follows: g (x) =mex{g (y) | Y is the successor of X, where G (x) is
SG[X].
For example: To take the stone problem, there are 1 piles of n stones, each time only to take {1,3,4} a stone, the first to take the stone victory, then the number of SG value for how much.
sg[0]=0,f[]={1,3,4},
X=1, you can take 1-f{1} a stone, the remaining {0}, mex{sg[0]}={0}, so sg[1]=1;
x=2, you can take 2-f{1} a stone, the remaining {1}, mex{sg[1]}={1}, so sg[2]=0;
X=3, you can take away 3-f{1,3} a stone, the remaining {2,0}, mex{sg[2],sg[0]}={0,0}, so sg[3]=1;
X=4, you can take away 4-f{1,3,4} a stone, the remaining {3,1,0}, mex{sg[3],sg[1],sg[0]}={1,1,0}, so sg[4]=2; X=5, you can take away 5-f{1,3,4} a stone, the remaining {4,2,1}, mex{sg[4],sg[2],sg[1]}={2,0,1}, so sg[5]=3;
And so on .....
x012345678....
SG[X] 010123201....
Calculates the SG value from the 1-n range.
F (the number of steps a store can take, f[0] indicates how many ways can be used).
F[] need to sort from small to large
1. The optional step number is 1~m continuous integer, directly takes the model, the SG (x) = x% (m+1); 2. Optional steps for any step, SG (x) = x;
3. The optional step number is a series of discontinuous number, with GETSG () calculation
Template 1 is as follows (SG play table):
F[]: The number of stones you can take away
//sg[]:0~n the SG function value
//hash[]:mex{}
int f[n];//The number of stones that can be removed
int sg[n];//0~n sg function Value
int hash[n];
void getsg (int n) {
memset (sg,0,sizeof (SG));
for (int i = 1; I <= n; i++) {
memset (hash,0,sizeof (Hash));
for (int j = 1; f[j] <= i; j +)
Hash[sg[i-f[j]] = 1;
for (int j = 0; J <= N; j +) { //mes{} The smallest nonnegative integer
if (hash[j] = = 0) {
sg[i] = j;
Break;}}}
Template 2 is as follows (DFS):
Note that the S array is sorted from small to large the SG function to be initialized to-1 for each set just initialize 1 times
//n is the size of the set S S[i] is a special rule of the definition of the array
int s[n],sg[n],n;
BOOL Vis[n];
int dfs_sg (int x) {
if (sg[x]!=-1) return
sg[x];
memset (Vis) (vis,0,sizeof);
for (int i = 0; i < n; ++i) {
if (x >= s[i]) {
dfs_sg (x-s[i));
Vis[sg[x-s[i]]] = 1;
}
}
for (int i = 0;; ++i) {
if (!vis[i]) {
e = i;
return sg[x] = i;}}
HDU1848 transmission door: http://acm.hdu.edu.cn/showproblem.php?pid=1848
The main effect of the topic:
Take the stone problem, a total of 3 piles of stones, each time can only take Fibonacci number of stones, the first to take the stone winner, ask the winning or the next victory.
Algorithm idea:
The optional number of steps is a series of discontinuous numbers (Fibonacci numbers), which can be obtained by GETSG function.
The final result is the result of all the SG values being different or.
http://blog.csdn.net/shuimu12345678/article/details/7677043
#include <iostream>
#include < cstring>
#include <cstdio>
using namespace std;
const int MAXN = 1005;
int F[MAXN], SG[MAXN], HASH[MAXN];
void getsg (int n)
{
memset (SG, 0, sizeof (SG));
for (int i = 1; I <= n; i++)
{
memset (hash, 0, sizeof (hash));
for (int j = 1; f[j] <= i && f[j] <= i; j +)
Hash[sg[i-f[j]] = 1;
for (int j = 0; J <= N; j +)
if (hash[j] = = 0)
{
sg[i] = j;
break;
}
}} int main ()
{
f[0] = f[1] = 1;
for (int i = 2; I <= i++)
f[i] = f[i-1] + f[i-2];
GETSG (1000);
int m, n, p;
while (scanf ("%d%d%d", &m, &n, &p)!= EOF, m+n+p)
{
if (sg[m) ^ sg[n] ^ sg[p])
puts ("Fibo"); C33/>else
puts ("Nacci");
}
return 0;
}