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值增加与否,我们都可以 ...
随机推荐
- 深度学习将会变革NLP中的中文分词——TODO 待好好细看
见:https://www.leiphone.com/news/201608/IWvc75oJglAIsDvJ.html TODO 待好好细看
- BZOJ 1041 数学
思路: $x^2+y^2=r^2$$y=\sqrt{(r+x)(r-x)}$令$ d=gcd(r+x,r-x)$设A=$(r-x)/d$ $B=(r+x)/d$则$gcd(A,B)=1$$y^2=d^ ...
- BZOJ 3509 分块FFT
思路: 跟今年WC的题几乎一样 (但是这道题有重 不能用bitset水过去) 正解:分块FFT http://blog.csdn.net/geotcbrl/article/details/506364 ...
- Java多线程编程那些事:volatile解惑--转
http://www.infoq.com/cn/articles/java-multi-thread-volatile/ 1. 前言 volatile关键字可能是Java开发人员“熟悉而又陌生”的一个 ...
- SQLServer int转float
例: select 2/4 会得到0 改为 select 2/4.0 则会得到0.500000 也同时达到了int转float的效果
- art-template简单使用
art-template是一款较通用的前端模板引擎. 简单的使用方法如下: 具备3个要素 1)模板 <script type="text/template" id=" ...
- arttemplate.js简洁写法案例
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...
- 使用vs2017创建项目并添加到git中
参考 https://blog.csdn.net/qq373591361/article/details/71194651 https://blog.csdn.net/boonya/article/d ...
- NEFU 116 两仪剑法 【求最小公倍数】
题目链接:http://acm.nefu.edu.cn/JudgeOnline/status.php?problem_id=116&order=1 解题思路:求最小公倍数 #include&l ...
- lambda表达式、匿名函数
lambda表达式是函数式编程中的匿名函数语法规范. In computer programming, an anonymous function (function literal, lambda ...