传送门
【题目分析】
SG入门题吧。
首先根据SG定理,三堆石子是互相独立的,所以整个游戏的sg值就是三堆石子的sg值异或和。
考虑如何计算sg值:
直接上暴力,先将前20个fibonacci求出来(因为石子数不会超过1e3),显然,gs(0)=0,然后按照gs的定义方式直接枚举1-1000所有状态的gs值,每一个状态直接枚举所有不大于他的斐波那契数减去即后继,再算一下mex就行了。
【代码~】
#include<bits/stdc++.h>
using namespace std;
const int MAXN=1e3+10;
int n,m,k;
int fib[MAXN];
int exist[MAXN],sg[MAXN];
void pre(){
fib[0]=fib[1]=1;
for(int i=2;i<=20;++i)
fib[i]=fib[i-1]+fib[i-2];
for(int i=1;i<=1e3;++i){
memset(exist,0,sizeof(exist));
for(int j=0;j<=20&&fib[j]<=i;++j)
exist[sg[i-fib[j]]]=1;
for(int j=0;j<=1e3;++j){
if(!exist[j]){
sg[i]=j;
break;
}
}
}
}
int main(){
pre();
while(scanf("%d%d%d",&n,&m,&k)&&(n|m|k)){
int ans=sg[n]^sg[m]^sg[k];
if(!ans)
puts("Nacci");
else
puts("Fibo");
}
return 0;
}
本文介绍了一道使用SG定理解决的博弈论入门题,通过预处理Fibonacci数列并利用动态规划计算各状态的SG值,最终实现对三堆石子游戏胜负判断的快速求解。
2831

被折叠的 条评论
为什么被折叠?



