Fibonacci again and again

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

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
 
 
 

取石子问题,一共有3堆石子,每次只能取斐波那契数个石子,先取完石子者胜利,问先手胜还是后手胜

 
求sg值,
 #include <bits/stdc++.h>
using namespace std; /*
s数组表示合法移动集合,从小到大排序。sNum合法移动个数
sg数组初始化为-1,对每个集合s仅需初始化1次
*/
const int MAXN = ;//s集合大小
const int MAXM = + ;//
int s[MAXN], sNum;
int sg[MAXM]; int dfsSg(int x)
{
if (sg[x] != -) {
return sg[x];
}
int i;
bool vis[MAXN];//sg值小于等于合法移动个数sNum memset(vis, false, sizeof(vis));
for (i = ; i < sNum && s[i] <= x; ++i) {
dfsSg(x - s[i]);
vis[sg[x - s[i]]] = true;
}
for (i = ; i <= sNum; ++i) {
if (!vis[i]) {
sg[x] = i;
break;
}
}
return sg[x];
} int main()
{
int i;
s[] = ;
s[] = ;
for (i = ; i < MAXN; ++i) {
s[i] = s[i - ] + s[i - ];
//printf("%d %d\n", i, s[i]);
}
sNum = ;
int m, n, p;
int sum;
memset(sg, -, sizeof(sg));
while (~scanf("%d%d%d", &m, &n, &p)) {
if (m == && n == && p == ) {
break;
}
dfsSg(m);
dfsSg(n);
dfsSg(p);
sum = sg[m] ^ sg[n] ^ sg[p];
if (sum != ) {
printf("Fibo\n");
} else {
printf("Nacci\n");
}
}
return ;
}
 #include <bits/stdc++.h>
using namespace std; /*
s数组表示合法移动集合,从小到大排序。sNum合法移动个数
sg值对每个集合s仅需求一次
*/
const int MAXN = ;//s集合大小
const int MAXM = + ;//
int s[MAXN], sNum;
int sg[MAXM];
bool exist[MAXN];//sg值小于等于合法移动个数sNum void getSg(int n)
{
int i, j;
sg[] = ;//必败态
for (i = ; i <= n; ++i) {
memset(exist, false, sizeof(exist));
for (j = ; j < sNum && s[j] <= i; ++j) {
exist[sg[i - s[j]]] = true;
}
for (j = ; j <= sNum; ++j) {
if (!exist[j]) {
sg[i] = j;
break;
}
}
}
} int main()
{
int i;
s[] = ;
s[] = ;
for (i = ; i < MAXN; ++i) {
s[i] = s[i - ] + s[i - ];
//printf("%d %d\n", i, s[i]);
}
sNum = ;
int m, n, p;
int sum;
getSg();
while (~scanf("%d%d%d", &m, &n, &p)) {
if (m == && n == && p == ) {
break;
}
sum = sg[m] ^ sg[n] ^ sg[p];
if (sum != ) {
printf("Fibo\n");
} else {
printf("Nacci\n");
}
}
return ;
}

hdu 1848 Fibonacci again and again(sg)的更多相关文章

  1. hdu 1848 Fibonacci again and again (SG)

    题意: 3堆石头,个数分别是m,n,p. 两个轮流走,每走一步可以选择任意一堆石子,然后取走f个.f只能是菲波那契中的数(即1,2,3,5,8.....) 取光所有石子的人胜. 判断先手胜还是后手胜. ...

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

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

  3. HDU 1848 Fibonacci again and again(SG函数入门)题解

    思路:SG打表 参考:SG函数和SG定理[详解] 代码: #include<queue> #include<cstring> #include<set> #incl ...

  4. hdu 1848 Fibonacci again and again (初写SG函数,详解)

    思路: SG函数的应用,可取的值为不连续的固定值,可用GetSG求出SG,然后三堆数异或. SG函数相关注释见代码: 相关详细说明请结合前一篇博客: #include<stdio.h> # ...

  5. hdu 1848 Fibonacci again and again(简单sg)

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

  6. 题解报告:hdu 1848 Fibonacci again and again(尼姆博弈)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1848 Problem Description 任何一个大学生对菲波那契数列(Fibonacci num ...

  7. HDU 1848 Fibonacci again and again【SG函数】

    对于Nim博弈,任何奇异局势(a,b,c)都有a^b^c=0. 延伸: 任何奇异局势(a1, a2,… an)都满足 a1^a2^…^an=0 首先定义mex(minimal excludant)运算 ...

  8. 【HDU1848】Fibonacci again and again(博弈论)

    [HDU1848]Fibonacci again and again(博弈论) 题面 Hdu 你有三堆石子,每堆石子的个数是\(n,m,p\),你每次可以从一堆石子中取走斐波那契数列中一个元素等数量的 ...

  9. HDU 1024 Max Sum Plus Plus (动态规划)

    HDU 1024 Max Sum Plus Plus (动态规划) Description Now I think you have got an AC in Ignatius.L's "M ...

随机推荐

  1. 转载的shell命令73条

    1.检查远程端口是否对bash开放: echo >/dev/tcp/8.8.8.8/53 && echo "open" 2.让进程转入后台: Ctrl + z ...

  2. Linux中的系统挂载文件/etc/fstab

    [root@localhost ~]# cat /etc/fstab ## /etc/fstab# Created by anaconda on Wed Oct 5 15:21:46 2016## A ...

  3. 学习pyhton需要做哪些准备工作

    1:知道python个版本是有差异的 2:既然有差异,那么如何在不同项目不同版本的开发环境; ----------------------------------------------------- ...

  4. 瑞丽熵(renyi entropy)

    在信息论中,Rényi熵是Hartley熵,Shannon熵,碰撞熵和最小熵的推广.熵能量化了系统的多样性,不确定性或随机性.Rényi熵以AlfrédRényi命名.在分形维数估计的背景下,Rény ...

  5. php 数组 高效随机抽取指定条记录的算法

    php使用数组array_rand()函数进行高效随机抽取指定条数的记录,可以随机抽取数据库中的记录,适合进行随机展示和抽奖程序. 该算法主要是利用php的array_rand()函数,下面看一下ar ...

  6. 统计easyui datagrid某列之和显示在对应列下面

    项目需求要在表格下面加一行统计求和的,结果网上搜寻了一堆,要么说的不详细,高深大牛们的见解:要么实现不了,搜寻老半天修改出一个可以用的,做一下学习记录,新手菜鸟,欢迎指正和新解决方案. 最终效果图: ...

  7. Loadrunder脚本篇——文件下载

    下载简介 对 HTTP协议来说,无论是下载文件或者请求页面,对客户端来说,都只是发出一个GET请求,并不会记录点击后的“保存”.“另存为操作”. 如下,点击页面中tar.gz压缩包,用工具可以清楚的看 ...

  8. Java访问网络url,获取网页的html代码

    在Java中,Java.net包里面的类是进行网络编程的,其中,java.net.URL类和java.net.URLConection类是编程者方便地利用URL在Internet上进行网络通信.有两种 ...

  9. windows通过ftp下载linux文件

    # windows 下载 linux的文件>> ftp <domain_or_ip>>> <input_username>>> <in ...

  10. ES6 随记(2)-- 解构赋值

    上一章请见: 1. ES6 随记(1)-- let 与 const 3. 解构赋值 a. 数组的解构赋值 let [a1, b1, c1] = [1, 2, 3]; console.log(a1, b ...