P4994 终于结束的起点

讲道理,洛谷上面许多题让我知道了什么叫做理科生的浪漫

这道题拿道题面的时候,第一反应就是斐波那契数列,具体实现这里就不赘述了。

题目中说求最小的f[i]%m0&&f[i+1]%m1这个情况时的i,第一个想法就是用一个无限循环,一直模拟斐波那契数列,每一次求出来的斐波那契都进行一次判断,此时找出来的第一个斐波那契就是求出来的最小值(代码就不放出来了)

看看那个难度,看看那个数据范围,想都不用想,这种做法明显会超时和RE,太原始了。就算是开了unsigned long long什么的,也只有40分,至于矩阵乘法,本蒟蒻不会,至于有没有用,那我也不知道了

因为在操作的时候,我的第一种做法是在判断是否为0和1的时候才MOD的,另外一种做法就是在算的时候就是MOD,学了其实先后顺序没有什么影响,这个时候有80分了,这能解决很多数据过大的问题

#include<bits/stdc++.h>
using namespace std;
unsigned long long m,f[100005];
int main(){
	cin>>m;
	f[0]=0,f[1]=1;
	for(register int i=2;i<=9999999;i++){
		f[i]=(f[i-1]+f[i-2])%m;
		if(f[i-1]%m==0&&f[i]%m==1){
			printf("%d",i-1);
			return 0;
		}
	}
	return 0;
}
                                         

这个时候我们的剩下两个错误点是RE,一般都是有关于什么数组溢出之类的问题,那么内存空间的大小就需要解决。回归到斐波那契的实质,其实它的操作只在于三个数字之间,那么我们可以明白,这样你就不必开一个数组记录每一次的值,如果不好理解,最多用6个变量就可以了,但其实3个足矣,这样这道题就满分了

#include<bits/stdc++.h>
using namespace std;
long long m,a=0,b=1,c=1;
int main(){
	cin>>m;
	for(long long i=1;i<=9999999;i++){
		c=a,a=b,b=(a+c)%m;
		if(a%m==0&&b%m==1){
			cout<<i;
			return 0;
		}
	}
	return 0;
}

对于斐波那契数列涉及到的一些mod和加法运算,是可以在运算的时候处理的,这样可以保证数据不会超限;在这样的情况下,还要去考虑数组是否溢出,对于这个的处理,应该在于对于一些特殊运算的本质不够了解,知道题就可以在3个数之间不断转换达到同样的目的

而像计算系数这类的题,加上系数的杨辉三角是和组合数有关的,但也是可以找规律的,所以对于这类和数学知识挂钩的题目,应该去寻找一些普遍规律,或者说去寻找运算的本质是什么

原文地址:https://www.cnblogs.com/Poetic-Rain/p/13067961.html