您的位置:首页 > 其它

hdu 1848 SG函数应用

2011-08-07 15:56 309 查看
做了这题才知道所有的ICG游戏都可以转化为nim game来做,中间就是SG值,对SG值的理解还是不够深

就这题而言,题目数据不大,可以考虑直接求出单个游戏0-1000的所有SG值,最后取异或之和即可

#include<iostream>
#include<queue>
#include<vector>
#include<algorithm>

using namespace std;

vector<int> fi;
vector<int> sg;

void init(){
vector<int> fsg;
fi.push_back(1);
fi.push_back(2);
int f0 = 1,f1 = 2,f2 = 0;
while(f2 <= 1000){//求fibonacci数
f2 = f0 +f1;
fi.push_back(f2);
f0 = f1; f1 = f2;
}
sg.push_back(0);
for(int i = 1;i <= 1000;i++){//求1-1000的SG值,模拟mex{}运算,因为这里是预处理,并不会当浪费多少时间
for(int j = 0;fi[j] <= i;j++){//把当前后继的SG值放到fsg中
int num = i-fi[j];
fsg.push_back(sg[num]);
}

//--------模拟mex{}运算-------------
sort(fsg.begin(),fsg.end());
if(fsg.size() == 1){
if(fsg[0]){
sg.push_back(0);
}
else
sg.push_back(1);
fsg.clear();//每次清空
continue;
}
for(vector<int>::size_type j = 1;j < fsg.size();j++){
if(fsg[0]){
sg.push_back(0);
break;
}
if(fsg[j]-fsg[j-1] > 1){
sg.push_back(fsg[j-1]+1);
break;
}
if(j == fsg.size()-1)
sg.push_back(fsg[j]+1);
}
fsg.clear();//每次清空
}
}

int main()
{
init();
while(1){
int m,n,p;
cin >>m >>n >>p;
if(!m && !n && !p)
break;
int sum = sg[m]^sg
^sg[p];//游戏的SG值==所有子游戏的SG值
if(sum)
cout <<"Fibo" <<endl;
else
cout <<"Nacci" <<endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: