Game-sg function

Nim game: 

   1. A state is a must-defeat state if and only if all its successors are a must-win state.

 2. A state is a must-win state if and only if it has at least one successor is a must-defeat state.

For the Nim game, scientists have long given a theorem (Bouton theorem): the state (x1, x2.....xn) is a must-defeat state if and only if x1^x2^......^ xn = 0, which means that all numbers are XORed and operated, also called Nim sum. [It can be proved that when Nim sum is 0, it is a must-defeat state, and when it is not 0, it is a must-win state. This is because, when the current state is 0, an operation performed can always make Nim sum non-zero (because of the change For any number (that is, any pile of stones), its binary form will change by one or more digits. At this time, the Nim sum, which is 0 on all of you, will change (some digits will become 1)) , That is, all successors are in a must-win state; when the current state is non-zero, there must be an operation that can make Nim sum 0 (just work on the bits that are 1 in the Nim sum binary), That is to say, there must be a successor state that is bound to fail. This is Bouton's theorem .

Bouton theorem is essentially a specific application of SG theorem. What is the SG theorem?

SG theorem:

Sprague-Grundy theorem (SG theorem): The SG function of the game sum is equal to the Nim sum of the SG function of each game. In this way, each subgame can be divided and conquered, thus simplifying the problem. The Bouton theorem is a direct application of the Sprague-Grundy theorem in the Nim game, because the SG function of a single-stack Nim game satisfies SG(x) = x.

For the SG theorem:

First define the mex (minimal excludant) operation, which is an operation applied to a set, representing the smallest non-negative integer that does not belong to this set. For example, mex{0,1,2,4}=3, mex{2,3,5}=0, mex{}=0.

This step should be very simple, that is, the new operation is defined as mex.

For any state x, define SG(x) = mex(S), where S is the set of SG function values ​​of the subsequent states of x (that is, the value in the above mex). The final return value (that is, SG(X)) is 0 as the point of failure, and if it is not zero, the point is to win.

To further explain S, it is the number of moves that can be given in the meaning of the question. For example, a pile of stones can only take 1, 3, 5, and 7 at a time, so the S array is 1, 3, 5, 7.

What if there are multiple piles of stones in a game? We only need to call the sg function on each pile of stones, and XOR all the values ​​obtained. If the result is 0, the situation will be defeated. Otherwise, it is a must.

#include<cstdio>
#include <iostream>
#include <cstring>
using namespace std;
const int MAX_N = 100;
int sg[MAX_N];//sg函数
bool vis[MAX_N];//标记数组

void solve(int n) {
    memset(vis, false, sizeof(vis));
    for (int i = 0; i < n; ++i)
            vis[sg[i]] = true;
    for (int i = 1; i <= n; ++i)//因为可以分成两堆,如果三堆,就写三重循环
        for (int j = 1; j <= n; ++j) {
            if (i + j == n) vis[sg[i] ^ sg[j]] = true;
        }
    int i;
    for (i = 0; ; ++i)//没有i < n,如果都不成立,最后i = n
        if (!vis[i]) break;
    sg[n] = i;
    cout << "sg[" << n << "]=" << i << endl;
}

 

Guess you like

Origin blog.csdn.net/qie_wei/article/details/88170092