SG函数题目
hdu1848 Fibonacci again and again
题意
有三堆石子,数量都不超过\(1000\),两人轮流取石子,每次取的石子个数只能是斐波那契数列的元素值,判断胜败
题解
计算出斐波那契数列,\(SG\)函数打表
#include<iostream>
#include<cstdio>
#include<vector>
#include<stack>
#include<queue>
#include<set>
#include<map>
#include<cstring>
#include<string>
#include<sstream>
#include<cmath>
#include<ctime>
#include<climits>
#include<algorithm>
#define LL long long
#define PII pair<int,int>
#define PLL pair<LL,LL>
#define PLI pair<LL,int>
#define pi acos(-1.0)
#define eps 1e-6
#define lowbit(x) x&(-x)
using namespace std;
int fib[20];
int a,b,c,sg[1010],book[1010],len;
int get_fib(){
fib[0]=fib[1]=1;
int i=2;
while(fib[i-1]+fib[i-2]<=1000){
fib[i]=fib[i-1]+fib[i-2];
i++;
}
return i;
}
void get_sg(){
for(int i=1;i<=1000;i++){
memset(book,0,sizeof(book));
for(int j=0;j<len && fib[j]<=i;j++){
book[sg[i-fib[j]]]=1;
}
for(int j=0;j<=1000;j++){
if(!book[j]){
sg[i]=j;
break;
}
}
}
}
int main(){
len=get_fib();
memset(sg,-1,sizeof(sg));
sg[0]=0;
get_sg();
while(~scanf("%d %d %d",&a,&b,&c) && (a || b || c)){
if((sg[a]^sg[b]^sg[c])==0) printf("Nacci\n");
else printf("Fibo\n");
}
}
hdu1517 A Multiplication Game
题意
\(p=1\),两个人轮流为\(p\)乘上\([2,9]\)之中的一个数,最终使得\(p\geq n\)的人获胜,判断胜败
其中\(1<n<4294967295\)
题解
\(map\)存储\(SG\)函数,\(SG\)函数打表
#include<iostream>
#include<cstdio>
#include<vector>
#include<stack>
#include<queue>
#include<set>
#include<map>
#include<cstring>
#include<string>
#include<sstream>
#include<cmath>
#include<ctime>
#include<climits>
#include<algorithm>
#define LL long long
#define PII pair<int,int>
#define PLL pair<LL,LL>
#define PLI pair<LL,int>
#define pi acos(-1.0)
#define eps 1e-6
#define lowbit(x) x&(-x)
using namespace std;
const LL m=4294967295;
LL n;
map<LL,LL> sg;
void get_sg(LL x){
if(sg.count(x)) return;
int book[10]={0};
for(int i=2;i<=9;i++){
if(!sg.count(x/i)) get_sg(x/i);
book[sg[x/i]]=1;
}
for(int i=0;i<9;i++){
if(!book[i]){
sg[x]=i;
break;
}
}
}
int main(){
sg[0]=0;
while(~scanf("%lld",&n)){
n--;
get_sg(n);
if(sg[n]==0) printf("Ollie wins.\n");
else printf("Stan wins.\n");
}
}