ACM-SG函数之Fibonacci again and again——hdu1848
Fibonacci again and again
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 4248 Accepted Submission(s): 1768
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 1 1
1 4 1
0 0 0
Fibo
Nacci
首先定义mex(minimal excludant)运算,这是施加于一个集合的运算。表示最小的不属于这个集合的非负整数。
比如mex{0,1,2,4}=3、mex{2,3,5}=0、mex{}=0。
对于一个给定的有向无环图,定义关于图的每一个顶点的Sprague-Grundy函数g例如以下:g(x)=mex{ g(y) | y是x的后继 },这里的g(x)即sg[x]
比如:取石子问题,有1堆n个的石子。每次仅仅能取{1,3,4}个石子,先取完石子者胜利,那么各个数的SG值为多少?
sg[0]=0,f[]={1,3,4},
x=1时,能够取走1-f{1}个石子,剩余{0}个,mex{sg[0]}={0},故sg[1]=1;
x=2时,能够取走2-f{1}个石子,剩余{1}个,mex{sg[1]}={1},故sg[2]=0;
x=3时,能够取走3-f{1,3}个石子,剩余{2,0}个,mex{sg[2],sg[0]}={0,0},故sg[3]=1;
x=4时,能够取走4-f{1,3,4}个石子。剩余{3,1,0}个,mex{sg[3],sg[1],sg[0]}={1,1,0},故sg[4]=2;
x=5时。能够取走5-f{1,3,4}个石子。剩余{4,2,1}个,mex{sg[4],sg[2],sg[1]}={2,0,1},故sg[5]=3;
以此类推.....
x 0 1 2 3 4 5 6 7 8....
sg[x] 0 1 0 1 2 3 2 0 1...
计算从1-n范围内的SG值。
f(存储能够走的步数,f[0]表示能够有多少种走法)
f[]须要从小到大排序
1.可选步数为1~m的连续整数,直接取模就可以。SG(x) = x % (m+1);
2.可选步数为随意步,SG(x) = x;
3.可选步数为一系列不连续的数,用GetSG()计算
上述是自jumping_frog博文的建立SG模板时的解释,稍后我也会做个SG函数的模板。
// 获得SG数组函数模板。t代表f数组的个数,n代表要求的sg数组上限
// f数组就是能取的个数(对于此题就是Fibonacci数列
// 有时,对于t已知就不须要单独传參
void get_sg(int t,int n)
{
int i,j;
memset(sg,0,sizeof(sg));
for(i=1;i<=n;i++)
{
memset(mex,0,sizeof(mex));
// 对于属于g(x)后继的数置1
for( j=1 ;j<=t && fib[j]<=i ;j++ )
mex[sg[i-fib[j]]]=1;
// 找到最小不属于该集合的数
for( j=0 ; j<=n ; j++ )
if(!mex[j])
break;
sg[i] = j;
}
}
/************************************************
*************************************************
* Author:Tree *
*From :http://blog.csdn.net/lttree *
* Title : Fibonacci again and again *
*Source: hdu 1848 *
* Hint : SG *
*************************************************
*************************************************/
#include <stdio.h>
#include <string.h>
int fib[21]; //fib保存Fibonacci数列
int sg[1001];//sg[]来保存SG值
bool mex[1001];//mex{}
// 构建SG数组,函数各步骤意义详见上面模板
void get_sg(int n)
{
int i,j;
memset(sg,0,sizeof(sg));
for(i=1;i<=n;i++)
{
memset(mex,0,sizeof(mex));
for( j=1 ;fib[j]<=i ;j++ )
mex[sg[i-fib[j]]]=1; for( j=0 ; j<=n ; j++ )
if(!mex[j])
break;
sg[i] = j;
}
}
int main()
{
int i,m,n,p;
// 构建Fibonacci数列
fib[0]=1,fib[1]=1;
for(i=2;i<21;++i) fib[i]=fib[i-1]+fib[i-2];
// 预处理获得sg数组
get_sg(1000);
while( scanf("%d%d%d",&m,&n,&p) && m+n+p )
{
if( (sg[m]^sg[n]^sg[p])==0 ) printf("Nacci\n");
else printf("Fibo\n");
}
return 0;
}
ACM-SG函数之Fibonacci again and again——hdu1848的更多相关文章
- hdu-------(1848)Fibonacci again and again(sg函数版的尼姆博弈)
Fibonacci again and again Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Jav ...
- HDU 1848 Fibonacci again and again(SG函数)
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission( ...
- HDU1848 Fibonacci again and again SG函数
Fibonacci again and again Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Jav ...
- HDU 1848 Fibonacci again and again (斐波那契博弈SG函数)
Fibonacci again and again Time Limit: 1000MS Memory Limit: 32768KB 64bit IO Format: %I64d & ...
- HDU1848 Fibonacci again and again(SG 函数)
任何一个大学生对菲波那契数列(Fibonacci numbers)应该都不会陌生,它是这样定义的: F(1)=1; F(2)=2; F(n)=F(n-1)+F(n-2)(n>=3); 所以,1, ...
- 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)运算 ...
- hdu 1848 Fibonacci again and again (初写SG函数,详解)
思路: SG函数的应用,可取的值为不连续的固定值,可用GetSG求出SG,然后三堆数异或. SG函数相关注释见代码: 相关详细说明请结合前一篇博客: #include<stdio.h> # ...
- HDU 1848 Fibonacci again and again(SG函数入门)题解
思路:SG打表 参考:SG函数和SG定理[详解] 代码: #include<queue> #include<cstring> #include<set> #incl ...
- 【博弈论】【SG函数】hdu1848 Fibonacci again and again
某个状态的SG函数被定义为 除该状态能一步转移到的状态的SG值以外的最小非负整数. 有如下性质:从SG值为x的状态出发,可以转移到SG值为0,1,...,x-1的状态. 不论SG值增加与否,我们都可以 ...
随机推荐
- md5 c# unicode 互换(原创)
php 代码 $input='中国'; $result= md5($input); $temp=iconv("UTF-8", "UTF16LE", $input ...
- HTML中href、src区别
href是Hypertext Reference的缩写,表示超文本引用.用来建立当前元素和文档之间的链接.常用的有:link.a.例如: <link href="reset.css&q ...
- SwiftUI 官方教程(六)
6. 在列表和详情之间设置导航 虽然列表已经能显示了,但是我们还不能通过点击单个地标来查看地标详情页面.SwiftUI教程 把 list 嵌入一个 NavigationView 中,并把每个 row ...
- POJ 1654 乱搞题?
题意: 从一个点出发,8个方向,给出每一步的方向,求出走过的路径形成的多边形的面积. 思路: 先普及一下向量叉乘.. (摘自度娘) 也就是x1y2-x2y1. 那这不就好说了嘛. 一个经过原点的闭合多 ...
- java三大版本解析
JAVA三大版本代表着JAVA技术的三个应用领域:JAVASE.JAVAME.JAVAEE. JAVA以前很长一段时间被称为JAVA2,所以现在很多人习惯称为J2SE.J2ME.J2EE,它们表示的含 ...
- Linux下实现视频读取
V4L(video4linux是一些视频系统,视频软件.音频软件的基础,经常时候在需要采集图像的场合,如视频监控,webcam,可视电话,经常使用在embedded linux中是linux嵌入式开发 ...
- 小程序-wx:for
wx:for (列表渲染) index默认数组下标item默认数组当前项的变量名 数组是对象的形式,单纯写{{item}},结果是[object object]的形式,必须加对象名,并且对象名基本设置 ...
- 使用Caffe预测遇到的问题
1. 在使用网络预测图像时, prediction = net.predict( [input_image] ) 出现: net.image_dims[0] 不是整数情况, (2).甚至以为np.ze ...
- LINQ(Language Integrated Query)
LINQ http://www.cnblogs.com/lifepoem/archive/2011/12/16/2288017.html LINQ是.NET Framework 3.5的新特性,其全称 ...
- 关于pc端 app端pdf,word xls等文件预览的功能
第一种用H5标签<iframe>标签实现 返回的文件类型,文件流,文件流返回必须在设置 contentType对应的Mime Type, 返回文件的物理位置. 已经实测可以支持的文件类型 ...