hdu 1848 Fibonacci again and again(sg)
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
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、 最先取光所有石子的人为胜者;
假设双方都使用最优策略,请判断先手的人会赢还是后手的人会赢。
m=n=p=0则表示输入结束。
1 4 1
0 0 0
Nacci
取石子问题,一共有3堆石子,每次只能取斐波那契数个石子,先取完石子者胜利,问先手胜还是后手胜
#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)的更多相关文章
- hdu 1848 Fibonacci again and again (SG)
题意: 3堆石头,个数分别是m,n,p. 两个轮流走,每走一步可以选择任意一堆石子,然后取走f个.f只能是菲波那契中的数(即1,2,3,5,8.....) 取光所有石子的人胜. 判断先手胜还是后手胜. ...
- hdu 1848 Fibonacci again and again(SG函数)
Fibonacci again and again HDU - 1848 任何一个大学生对菲波那契数列(Fibonacci numbers)应该都不会陌生,它是这样定义的: F(1)=1; F(2)= ...
- HDU 1848 Fibonacci again and again(SG函数入门)题解
思路:SG打表 参考:SG函数和SG定理[详解] 代码: #include<queue> #include<cstring> #include<set> #incl ...
- hdu 1848 Fibonacci again and again (初写SG函数,详解)
思路: SG函数的应用,可取的值为不连续的固定值,可用GetSG求出SG,然后三堆数异或. SG函数相关注释见代码: 相关详细说明请结合前一篇博客: #include<stdio.h> # ...
- 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 ...
- 题解报告:hdu 1848 Fibonacci again and again(尼姆博弈)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1848 Problem Description 任何一个大学生对菲波那契数列(Fibonacci num ...
- 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)运算 ...
- 【HDU1848】Fibonacci again and again(博弈论)
[HDU1848]Fibonacci again and again(博弈论) 题面 Hdu 你有三堆石子,每堆石子的个数是\(n,m,p\),你每次可以从一堆石子中取走斐波那契数列中一个元素等数量的 ...
- 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 ...
随机推荐
- 转载的shell命令73条
1.检查远程端口是否对bash开放: echo >/dev/tcp/8.8.8.8/53 && echo "open" 2.让进程转入后台: Ctrl + z ...
- Linux中的系统挂载文件/etc/fstab
[root@localhost ~]# cat /etc/fstab ## /etc/fstab# Created by anaconda on Wed Oct 5 15:21:46 2016## A ...
- 学习pyhton需要做哪些准备工作
1:知道python个版本是有差异的 2:既然有差异,那么如何在不同项目不同版本的开发环境; ----------------------------------------------------- ...
- 瑞丽熵(renyi entropy)
在信息论中,Rényi熵是Hartley熵,Shannon熵,碰撞熵和最小熵的推广.熵能量化了系统的多样性,不确定性或随机性.Rényi熵以AlfrédRényi命名.在分形维数估计的背景下,Rény ...
- php 数组 高效随机抽取指定条记录的算法
php使用数组array_rand()函数进行高效随机抽取指定条数的记录,可以随机抽取数据库中的记录,适合进行随机展示和抽奖程序. 该算法主要是利用php的array_rand()函数,下面看一下ar ...
- 统计easyui datagrid某列之和显示在对应列下面
项目需求要在表格下面加一行统计求和的,结果网上搜寻了一堆,要么说的不详细,高深大牛们的见解:要么实现不了,搜寻老半天修改出一个可以用的,做一下学习记录,新手菜鸟,欢迎指正和新解决方案. 最终效果图: ...
- Loadrunder脚本篇——文件下载
下载简介 对 HTTP协议来说,无论是下载文件或者请求页面,对客户端来说,都只是发出一个GET请求,并不会记录点击后的“保存”.“另存为操作”. 如下,点击页面中tar.gz压缩包,用工具可以清楚的看 ...
- Java访问网络url,获取网页的html代码
在Java中,Java.net包里面的类是进行网络编程的,其中,java.net.URL类和java.net.URLConection类是编程者方便地利用URL在Internet上进行网络通信.有两种 ...
- windows通过ftp下载linux文件
# windows 下载 linux的文件>> ftp <domain_or_ip>>> <input_username>>> <in ...
- ES6 随记(2)-- 解构赋值
上一章请见: 1. ES6 随记(1)-- let 与 const 3. 解构赋值 a. 数组的解构赋值 let [a1, b1, c1] = [1, 2, 3]; console.log(a1, b ...