http://baike.baidu.com/link?url=RvHq88XaFKNd0XJC97k2JWvIJSPZiLKvVhVnA_yCPR_K-cZhb2lLIjG3XHatW8VeyzLxbbOvYWqEtcc2RSdls_7mPQDbixegyJFRIBJFdj_
http://www.cnblogs.com/frog112111/p/3199073.html
兩人操控一個棋子要從起點到終點,每次可以走若干步(看下邊的三種規則),誰無路可走誰就輸。
對於一個子遊戲(之所以說是子游戲,是因爲情況可能不止一個棋子,比如兩人操作兩個棋子。可以認爲一個棋子是一個子遊戲。而總遊戲的勝利爲各個子游戲的sg的異或)(sg[i]爲0爲必敗點,不爲0爲必勝點)
三種規則
1.每次可以走任意步,那麼sg[i] = i,
2.每次可以走1~m步,那麼sg[i] = i%(m+1),
3對於不連續的步數。下面的函數。
#include<vector>
#include<iostream>
using namespace std;
vector<int> sg(20);
vector<int> f = {0,1,2,5};//每次可以走的步數,這裏設爲1,2,,5。f[0]無意義。
std::vector<int> hash0(20);//找到mex({sg[當前步數減去可以走的步數}),最小非負整數
void getsg(int n)
{
for(int i=0; i<sg.size(); i++) sg[i] = 0;
for(int i=1; i<=n; i++)
{
for(int i=0; i<hash0.size(); i++) hash0[i] = 0;
for(int j=1; f[j] <= i; j++)
{
hash0[sg[i-f[j]]] = 1;
}
for(int j=0; j <=n; j++)
{
if(hash0[j] == 0)
{
sg[i] = j;
break;
}
}
cout<<i<<" "<<sg[i]<<endl;
}
}
int main()
{
getsg(20);
return 0;
}