題目大意:在尼姆遊戲的基礎上,把能夠取的石頭個數限定了。用sg函式實現,每個計算出的sg值都等價於原尼姆遊戲中的一堆的石子數。
某一堆的石子數取走一定數量k後可以得到乙個新石子堆對應的sg值,也就是原石堆的所有分支的其中乙個。
這時候後手可以根據實際情況處理。sg值是子分支中沒有出現過的最小整數。
比如 原sg = 3的分支有sg = 0, sg = 1, sg = 2,那麼只要滿足sg的異或值為0,必定有另外乙個sg=3,只需要將其也變成對方所變成的分支即可。
又如原sg = 3的分支有sg = 0, sg = 1, sg = 2,sg = 4……sg=k,而另外乙個sg=3的分支為sg = 0, sg = 1, sg = 2。對方把3變成了k(k>3),而我方只要把k再變回3就可以了。這樣仍是成對存在了。
為什麼用dp打表wa了,沒找到問題,以後還是用記憶化搜尋吧,時間複雜度一樣的,也可能是我細節寫的不對。
#include#include#include#include#includeusing namespace std;
const int maxn = 100;
int match[maxn + 5];
int h[maxn + 5];
int sg[maxn * maxn + 5];
int m, l, k;
int dfs(int p)
bool vis[maxn*maxn+5] = ;
for (int i = 0; i < k; i ++)
}for (int i = 0; ; i ++)
}}int main()
scanf("%d", &m);
char ans[maxn + 5];
memset(sg, -1, sizeof(sg));
for (int i = 0 ; i < m; i ++)
int res = 0;
/** dfs */
sg[0] = 0;
for (int i = 0; i < l; i ++)
res ^= sg[h[i]];
}/** dp */
// sort(match, match + k);
// memset(sg, 0, sizeof(sg));
// bool _hash[maxn * maxn + 5] = ;
// int mx = *max_element(h, h + l);
// for (int i = 0; i <= mx; i ++)
// for (int j = 0;; j ++)
// }
// }
// for (int i = 0; i < l; i ++)
ans[i] = res ? 'w':'l';
}ans[m] = 0;
puts(ans);
}return 0;
}
POJ 2960 典型的sg函式
這道題之前做過的,但是晚上拿出來熟悉一下!但是runtime error!很奇怪,查!堅決不看之前的 後來突然乙個念頭 會不胡hash陣列沒有初始化!加了個hash 110 a了,忘記的是定義為全域性性質的陣列才會被編譯器自動初始化為0 非全域性的不會自動初始化!哎哎!教訓。poj 2960 res...
POJ2960 SG函式,模板題
題目大意 已知一次可拿個數的種類 求出先手是否勝利,若勝利輸出w否則輸出l sg函式模板 include const int n 10008 int a 110 sg n f n void sgt int a,int y,int z 題目 include include const int n 10...
POJ2960 S Nim(博弈論 sg函式)
題意 給出一系列石子堆,現在每次只能從乙個堆中拿出固定石子數,問輸贏結果。要點 跟nim博弈很像,但是這次每次只能拿固定個數,所以要用sg函式,下面是sg函式的具體定義 sg x mex sg y y是x的後繼結點 其中mex x x是乙個自然是集合 函式是x關於自然數集合的補集中的最小值,比如x ...