Summer exams 2: Nim change the game (Game Theory)

topic:

In fact, the basis of added nim game can not take the chance.

A plurality of multi-stack stones can be seen as a game, they are the starting point of the exclusive OR values ​​sg sg value of the entire game is up, if the sg is 1, the upper hand win, is 0, the flip win.

The key is how demand sg value: you can play table to find the law -> game situation be dynamic dfs even side , and then ask again dfs sg value (the value that is seeking mex)

Details: the DFS can go to a small range up to 20 (possibly reach, because the edge is too much), so do not doubt their own wrong when the cycle of death, may also be a number too large stones .

Law: number of stones is odd, mex value a [i] +1, even-numbered, mex value a [i] -1.

Playing table Code:

#include<bits/stdc++.h>
using namespace std;
#define N 25
#define M 100005
int tong[M][N],mexx[M],head[M],to[M],nex[M],tot=0,val[M],ndnum,fl[M];
void add(int a,int b) { to[++tot]=b; nex[tot]=head[a]; head[a]=tot; }
void dfs(int u)
{
    if(val[u]==0) return ;
    if(fl[u]==0){
        val[++ndnum]=val[u];
        add(u,ndnum); fl[ndnum]=1;
        dfs(ndnum);
    }
    for(int i=0;i<=val[u]-1;i++){
        val[++ndnum]=i;
        add(u,ndnum);
        fl[ndnum]=fl[u];
        dfs(ndnum);
    }
}
void SG(int u)
{
    if(val[u]==0) { mexx[u]=0; return ; }
    for(int i=head[u];i;i=nex[i]){
        int v=to[i];
        SG(v);
        tong[u][mexx[v]]=true;
    }
    for(int i=0;i<=20;i++)
    if(!tong[u][i]) { mexx[u]=i; return ; }
}
int main()
{
    for(int i=1;i<=10;i++){
        int id=++ndnum;
        val[id]=i; fl[id]=0;
        dfs(id);
        SG(id);
        printf("mex:%d %d\n",i,mexx[id]);
    }
}

 

Hit the table to find the code of law:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
int main()
{
    freopen("nim.in","r",stdin);
    freopen("nim.out","w",stdout);
    int T,n,a;
    scanf("%d",&T);
    while(T--){
        scanf("%d",&n);
        scanf("%d",&a);
        if(a&1) a++; else a--;
        ll ans=a;
        for(int i=2;i<=n;i++){
            scanf("%d",&a);
            if(a&1) a++;
            else a--;
            ans^=a;
        } 
        if(ans) printf("A\n");
        else printf("B\n");
    }
}
/*
2
2
1 2
2
2 2
*/

 

Guess you like

Origin www.cnblogs.com/mowanying/p/11402738.html