【找最小周期+循环节】HDU-1005 Number Sequence

在这里插入图片描述

注解

1、注意看n的范围很大,不能暴力破解。由于是mod 7,f(n)只跟f(n-1)和f(n-2)有关,因此最多也就只有49种情况,所以最多只需要找到f[50]就一定会出现循环了。
2、本题的关键就是找出从哪里开始循环,以及循环节的长度是多少(也就是函数周期性的最小周期)。本题采用的方法是,从前往后找,i从1开始,j从i+1开始,找到f[i]==f[j]&&f[i+1]==f[j+1],那么i就是循环的起始位置,循环节的长度就是j-i.
3、根据输入的n的大小,如果比start位置大,就进行取余操作。否则,直接输出。

代码

#include <iostream>

using namespace std;

const int maxn = 60;

int main() {

	int f[maxn];
	f[1] = 1;
	f[2] = 1;

	int A, B, n;
	cin>>A>>B>>n;

	while(A || B || n) {
		for(int i=3; i<maxn; i++) {
			f[i] = (A*f[i-1] + B*f[i-2]) % 7;
		}
		
		int start = -1;
		int len = -1;
		for(int i=1; i<maxn-1; i++){
			for(int j=i+1; j<maxn-1; j++){
				if(f[i]==f[j] && f[i+1]==f[j+1]){
					start = i;
					len = j-i;
				}
			}
		}
		
		if(n>start){
			n = start + (n-start)%len;
		}
		cout<<f[n]<<endl;
		cin>>A>>B>>n;
	}

	return 0;
}

结果

在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值