Fibonacci again and again

Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 6363    Accepted Submission(s): 2646

Problem Description
任何一个大学生对菲波那契数列(Fibonacci numbers)应该都不会陌生,它是这样定义的:
F(1)=1;
F(2)=2;
F(n)=F(n-1)+F(n-2)(n>=3);
所以,1,2,3,5,8,13……就是菲波那契数列。
在HDOJ上有不少相关的题目,比如1005 Fibonacci again就是曾经的浙江省赛题。
今天,又一个关于Fibonacci的题目出现了,它是一个小游戏,定义如下:
1、  这是一个二人游戏;
2、  一共有3堆石子,数量分别是m, n, p个;
3、  两人轮流走;
4、  每走一步可以选择任意一堆石子,然后取走f个;
5、  f只能是菲波那契数列中的元素(即每次只能取1,2,3,5,8…等数量);
6、  最先取光所有石子的人为胜者;

假设双方都使用最优策略,请判断先手的人会赢还是后手的人会赢。

 
Input
输入数据包含多个测试用例,每个测试用例占一行,包含3个整数m,n,p(1<=m,n,p<=1000)。
m=n=p=0则表示输入结束。
 
Output
如果先手的人能赢,请输出“Fibo”,否则请输出“Nacci”,每个实例的输出占一行。
 
Sample Input
1 1 1
1 4 1
0 0 0
 
Sample Output
Fibo
Nacci
 
Author
lcy
 
由于本题n的范围为1000,所以时间复杂度不是很高
下面两种方法的代码都可以过,,
15086248 2015-10-12 19:11:07 Accepted 1848 0MS 1576K 1320 B G++ 牟柏旭
 
   //f[]:可以取走的石子个数
//sg[]:0~n的SG函数值
//Hash[]:mex{}
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=;
const int K=;
int f[K],sg[N],Hash[N];
int k;
void getSG(int n)
{
memset(sg,,sizeof(sg));
for(int i=; i<=n; i++) {
memset(Hash,,sizeof(Hash));
for(int j=; f[j]<=i && j < k; j++) //k是f[]的有效长度
Hash[sg[i-f[j]]]=;
for(int j=; ; j++) { //求mes{}中未出现的最小的非负整数
if(Hash[j]==) {
sg[i]=j;
break;
}
}
}
}
int main(){
int x1,x2,x3;
f[]=;
f[]=;
for(int i=;i<=;i++)
f[i]=f[i-]+f[i-];
k=;
getSG();
while(scanf("%d%d%d",&x1,&x2,&x3)!=EOF){
if(x1==&&x2==&&x3==)
break;
int ans;
ans=sg[x1]^sg[x2]^sg[x3];
if(ans)
printf("Fibo\n");
else
printf("Nacci\n"); }
return ;
}

上面的打表的代码,下面附上dfs代码

15087133 2015-10-12 20:11:06 Accepted 1848 109MS 1880K 1060 B C++ 牟柏旭
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<algorithm> using namespace std;
const int k=;
int s[],sg[];
int getsg(int m)
{
int hash[]={};
int i;
for(i=;i<k;i++){
if(m-s[i]<)
break;
if(sg[m-s[i]]==-)
sg[m-s[i]]=getsg(m-s[i]);
hash[sg[m-s[i]]]=;
}
for(i=;;i++)
if(hash[i]==)
return i; }
int main()
{
int x[];
s[]=;
s[]=;
for(int i=;i<;i++)
s[i]=s[i-]+s[i-];
while(scanf("%d%d%d",&x[],&x[],&x[])!=EOF)
{
if(x[]==&&x[]==&&x[]==)
break;
int i; memset(sg,-,sizeof(sg));
sg[]=; int ans=; for(int i=;i<=;i++){
if(sg[x[i]]==-)
sg[x[i]]=getsg(x[i]);
ans^=sg[x[i]];
}
if(ans)
cout<<"Fibo"<<endl;
else cout<<"Nacci"<<endl; }
return ;
}
15087680 2015-10-12 20:35:01 Accepted 1848 140MS 1772K 1384B C++ 牟柏旭
    #include<cstdio>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=;
int knum;
int si[N],sg[];
int mex(int x)//求x的sg值(可作为模版应用)
{
if(sg[x]!=-)
return sg[x];
bool vis[N];
memset(vis,false,sizeof(vis));
for(int i=;i<knum;i++) {
int temp=x-si[i];
if(temp<)
break;
sg[temp]=mex(temp);
vis[sg[temp]]=true;
}
for(int i=;i<;i++) {
if(!vis[i]) {
sg[x]=i;
break;
}
}
return sg[x];
}
int main() { int x[]; while(scanf("%d%d%d",&x[],&x[],&x[])!=EOF) {
if(x[]==&&x[]==&&x[]==)
break;
si[]=;
si[]=;
for(int i=;i<;i++)
si[i]=si[i-]+si[i-];
knum=;
memset(sg,-,sizeof(sg));
sg[]=; int ans=; for(int j=;j<=;j++) { ans^=mex(x[j]);//尼姆博弈
}
if(ans==)
printf("Nacci\n");
else
printf("Fibo\n"); }
return ;
}
 

hdu 1848 sg——dfs&&打表双实现的更多相关文章

  1. hdu 2147 SG函数打表(手写也可以) 找规律

    kiki's game Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 40000/1000 K (Java/Others) Total ...

  2. HDU 1848 SG函数博弈

    Fibonacci again and again Problem Description   任何一个大学生对菲波那契数列(Fibonacci numbers)应该都不会陌生,它是这样定义的:F(1 ...

  3. hdu 1848(SG函数)

    Fibonacci again and again Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Jav ...

  4. hdu 1536 sg (dfs实现)

    S-Nim Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submi ...

  5. SG函数入门&&HDU 1848

    SG函数 sg[i]为0表示i节点先手必败. 首先定义mex(minimal excludant)运算,这是施加于一个集合的运算,表示最小的不属于这个集合的非负整数.例如mex{0,1,2,4}=3. ...

  6. hdu 1848 Fibonacci again and again(SG函数)

    Fibonacci again and again HDU - 1848 任何一个大学生对菲波那契数列(Fibonacci numbers)应该都不会陌生,它是这样定义的: F(1)=1; F(2)= ...

  7. HDU 2586 How far away(dfs+邻接表)

    How far away [题目链接]How far away [题目类型]dfs+邻接表 &题意: 题目大意:一个村子里有n个房子,这n个房子用n-1条路连接起来,接下了有m次询问,每次询问 ...

  8. HDU 2563 统计问题 (DFS + 打表)

    统计问题 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submi ...

  9. hdu1848(sg函数打表)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1848 题意:中文题诶- 思路:直接sg函数打表就好了 代码: #include <iostrea ...

随机推荐

  1. hasNextInt()方法

    hasNextInt()方法是判断控制台接收是否为数字,当你在控制台输入一个字符的时候,hasNextInt()判断你输入这个字符是不是数字,而不是接收值,当if判断通过之后执行接收,也就是你输入的那 ...

  2. /etc/default/useradd

    系统默认的shell在,/etc/default/useradd 中,添加用户的时候如果不指定shell,默认的shell就是该文件下制定的文件

  3. Python安装第三方库文件工具——pip

    Python安装第三方库文件一般使用pip. 1.pip的安装 (1)下载pip 进入https://pypi.python.org/pypi/pip#downloads

  4. JSON数组不用字符串转换的写法

    var organization = []; //机构组织 //初始化用户数据列表中用户机构列的数据源 admin.ajax("GetOrganizationInfo", null ...

  5. Codeforces Round #318 (Div. 2) B Bear and Three Musketeers (暴力)

    算一下复杂度.发现可以直接暴.对于u枚举a和b,判断一下是否连边,更新答案. #include<bits/stdc++.h> using namespace std; int n,m; ; ...

  6. codeforces Gym 100338F Spam Filter 垃圾邮件过滤器(模拟,实现)

    阅读题, 概要:给出垃圾邮件和非垃圾邮件的集合,然后按照题目给出的贝叶斯公式计算概率一封邮件是垃圾邮件的概率. 逐个单词判断,将公式化简一下就是在垃圾邮件中出现的次数和在总次数的比值,大于二分之一就算 ...

  7. iview 表单验证 input 用失去焦点事件 blur, select下拉选框 要用change事件 验证

    birthday: [{ required: true, message: '内容不能为空', trigger: 'blur' }],belongDept: [{ required: true, me ...

  8. 使用bat脚本调用py文件直接获取应用的包名和targetversion

    背景: 在上一篇已经介绍过如何利用python调用aapt获取包名 https://www.cnblogs.com/reseelei-despair/p/11078750.html 但是因为每次都要修 ...

  9. ubuntu 16.04 安装node.js 8.x

    引自 https://www.digitalocean.com/community/tutorials/how-to-install-node-js-on-ubuntu-16-04#how-to-in ...

  10. 第三届上海市大学生网络安全大赛wp&学习

    wp 0x00 p200 先分析了程序关键的数据结构 分析程序逻辑,在free堆块的时候没有清空指针,造成悬挂指针,并且程序中给了system('/bin/sh'),可以利用uaf 脚本如下: 1.先 ...