我只想说今晚做了两道巴什博弈的题,全用SG函数解的。脑洞真大。。。。
先简单说一下巴什博弈吧,一共有n块石头,两个人轮流取,每次至少取1块,至多取m块,问先手胜负情况。
思路:n=(m+1)*r+s,若s不为0,则先手必胜,取法为,先手先取s,然后每次第二个人取x块之后,先手取m+1-x块。
若s=0,则先手必败,第二个人取法同上。
其实两个题目是一样的。
先贴2149的SG函数代码
#pragma warning(disable:4996)
#include <cstdio>
#include <cstring>
using namespace std;
int sg[2500];
int vis[2500];
void getSG(int n, int m){
for (int i = m; i <= n + m; i++)sg[i] = 0;
for (int i = m - 1; i >= 0; i--){
memset(vis, false, sizeof vis);
for (int j = 1; j <= n; j++)vis[sg[i + j]] = true;
for (int j = 0; j < 2500; j++){
if (!vis[j]){
sg[i] = j;
break;
}
}
}
}
int main(){
int n, m;
while (~scanf("%d %d", &m, &n)){
getSG(n, m);
int cnt = 0;
for (int i = 1; i <= n; i++){
if (sg[i] == 0){
if (cnt >= 1)printf(" ");
printf("%d", i);
cnt++;
}
}
if (cnt == 0)puts("none");
else puts("");
}
return 0;
}
再贴2188的巴什博弈代码
#pragma warning(disable:4996)
#include <cstdio>
using namespace std;
int main(){
int t; scanf("%d", &t);
while (t--){
int n, m;
scanf("%d %d", &n, &m);
if (n % (m + 1) == 0)puts("Rabbit");
else puts("Grass");
}
return 0;
}