HDU1005Number Sequence题解以及想法

Number Sequence

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 225136    Accepted Submission(s): 57138


Problem Description

A number sequence is defined as follows:

f(1) = 1, f(2) = 1, f(n) = (A * f(n - 1) + B * f(n - 2)) mod 7.

Given A, B, and n, you are to calculate the value of f(n).  

 

Input

The input consists of multiple test cases. Each test case contains 3 integers A, B and n on a single line (1 <= A, B <= 1000, 1 <= n <= 100,000,000). Three zeros signal the end of input and this test case is not to be processed.  

 

Output

For each test case, print the value of f(n) on a single line.  

 

Sample Input

1 1 3 1 2 10 0 0 0

Sample Output

2 5 这是一道水题,但是由于菜鸡的我并不清楚到底要循环几次就束手无策,因为从1e8的范围就可以看出来,暴力一定会超时(1e8跑一遍差不多1s,但是不可能跑一遍就出来)  后来通过查题解知道了原来确实结果是循环(不然真的难办),但是循环次数最多也是49次,怎么算的呢?因为一组数据里面A,B的值是一定的,当f(n - 1)和f(n - 2)相同时,后面的结果就和之前一样,接下来就是开始循环了。于是乎,网上有题解n % 49的有,循环找f(n - 1), f(n - 2)都为1作为跳出找到循环节的也有,可是,这些都没考虑到当循环是11232323.......这样的(确实可以做得到,因为A,B每组数据不一定),找什么f(n - 1), f(n - 2)都为1,找什么49,都是错的,所以还得统计之前出现过的两位即可,我们开个int二维数组记录,数组的值是第一次出现的两个数后一个的位置,若为0则没出现。
#include <stdio.h>
#include <string.h>
int arr[100];
int k[7][7];
int main(void)
{
	int a, b, n;
	while(scanf("%d %d %d", &a, &b, &n) == 3 && (a || b || n))
	{
		memset(k, 0, sizeof(k));
		int i;
		arr[1] = arr[2] = 1;
		k[1][1] = 2;
		for(i = 3; i < 70; i++)
		{
			arr[i] = (a * arr[i - 1] + b * arr[i - 2]) % 7;
			if(!k[arr[i]][arr[i - 1]])//这两个排列没出现过 
				k[arr[i]][arr[i - 1]] = i;//标记第一次出现的位置 
			else//出现过 
				break;//那就找到了循环节,因为后面就一直重复第一次的位置到现在的位置中间的数字 
		}
		int m = k[arr[i]][arr[i - 1]];//m没啥意义,就是写k[arr[i]][arr[i - 1]]太麻烦了 
		int t = i - m;//找到循环位数 
		if(n <= m)//如果在之前,在循环之前,直接输出 
			printf("%d\n", arr[n]);
		else//在后面,则在循环节中某一个值 
			printf("%d\n", arr[(n - m) % t + m]);
	}
	return 0;
}

  杭电讨论板块网友提供的测试数据(因为题目的测试数据很水,% 49找1 1都能过)

247 602 35363857
376 392 9671521
759 623 18545473
53 399 46626337
316 880 10470347
0 0 0

------------------------------------------------------------------------------
Output:
4
3
5
2
3

 

上一篇:UITableViewCell 设置圆角


下一篇:剑指offer第49题:把字符串转换成整数