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值增加与否,我们都可以 ...
随机推荐
- Linux - 设置光盘,开机自动挂载。
设置光盘,开机自动挂载. 挂载, 在linux操作系统中, 挂载是指将一个设备(通常是存储设备)挂接到一个已存在的目录上. 我们要访问存储设备中的文件,必须将文件所在的分区挂载到一个已存在的目录上, ...
- 【POJ 1084】 Square Destroyer
[题目链接] http://poj.org/problem?id=1084 [算法] 迭代加深 [代码] #include <algorithm> #include <bitset& ...
- jQuery右键菜单contextMenu实例
URL: http://www.cnblogs.com/whitewolf/archive/2011/09/28/2194795.html http://www.blogjava.net/superc ...
- Hadoop MapReduce编程 API入门系列之join(二十六)(未完)
不多说,直接上代码. 天气记录数据库 Station ID Timestamp Temperature 气象站数据库 Station ID Station Name 气象站和天气记录合并之后的示意图如 ...
- ViewData与ViewBag的使用区别
在Asp.net MVC 3 web应用程序中,我们会用到ViewData与ViewBag,对比一下: ViewData ViewBag 它是Key/Value字典集合 它是dynamic类型对像 从 ...
- configparser (配置文件) 模块
主要内容来自景女神博客 内涵:该模块适用于配置文件的格式与windows ini文件类似,可以包含一个或多个节(section),每个节可以有多个参数(键=值). 常见文档格式: [DEFAULT] ...
- wcf 学习程序
(一)创建WCF Service (1)创建WCF Service类库 创建一个Class Library的项目: 删除掉默认的Class1.cs文件,然后添加一个WCF Service项目: Vis ...
- url 域名 主机名
1. url = 协议//主机名(包括服务器的计算机名+域名)/路径 https:// i. cnblogs.com /index.html .com是顶级域名,从右向左,每碰到一个".&q ...
- jQuery基本选择器模块
选择器模块 1.获取元素的基本操作 案例:给页面中的div和p设置边框样式 1.1 传统方式 -获取元素并设置样式 实现思路 1 通过 标签名 获取元素 2 遍历循环 设置样式 var dvs = d ...
- Android中图片旋转
Activity_main.xml文件配置 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/androi ...