码迷,mamicode.com
首页 > 其他好文 > 详细

HDOJ-1005 Number Sequence

时间:2015-02-21 01:22:39      阅读:166      评论:0      收藏:0      [点我收藏+]

标签:

http://acm.hdu.edu.cn/showproblem.php?pid=1005

给出两个初值f(1) = 1;f(2) = 1 和 递推公式f(n) = (a * f(n - 1) + b * f(n - 2)) % 7

输入a,b,n 要求输出f(n)

 1 <= n <= 100,000,000这个限制条件表示直接迭代n次注定是超时的结局

由迭代公式知道f(n)都由前两个数推导出来 而每个数都有7种可能 所以共有7*7=49种组合

所以根据鸽巢原理知 由该递推公式推导出50个连续的数,必有两对相同的数(形如1 1 2 3 4 5 6 1 1 2 3..中的1 1)

又因为a和b是常量,所以相同的两对数必会推出相同结果 这个效应传递下去就会导致循环周期的出现

所以该数列必有长度在49以内的循环周期

*但是周期不一定是从1 1开始的

*比如当a=605 b=903时 数列为1,1,3,2,6,4,5,1,3,2,6,4,5,1,3...可以看出周期为1,3,2,6,4,5 并不是从1 1 此处需注意

# include <stdio.h>

int f[55], a, b, n, Start, End;

bool Have_Circle(int pos)
{
	for(int j = 1; j + 1 < pos; j++)
	{
		if(f[j] == f[pos - 1] && f[j + 1] == f[pos])//若出现一对相同的数 说明有周期
		{
			Start = j;//周期起点
			End = pos - 2;//终点
			return true;
		}
	}
	return false;
}

int main()
{
	while(scanf("%d %d %d",&a, &b, &n) && a && b && n)
	{
		f[1] = f[2] = 1;

		for(int i = 3; i < 55; i++)
		{
			f[i] = (f[i - 1] * a + f[i - 2] * b) % 7;
			if(Have_Circle(i))//查看是否出现周期
				break;
		}

		//减去周期前的无用数字 模 周期长度
		n = (n - (Start - 1)) % (End - Start + 1);

		if(n)
			printf("%d\n",f[n + (Start - 1)]);
		else//若n == 0 则是周期最后一个数字
			printf("%d\n",f[End]);
	}

	return 0;
}

  

HDOJ-1005 Number Sequence

标签:

原文地址:http://www.cnblogs.com/linjiaman/p/4296800.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!