1005--Number Sequence

在这里插入图片描述

#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
int a,b;
long long n;
int f(int a,int b,long long n){
    
    
	if(n==1)
		return 1;
	else if(n==2)
		return 1;
 	else
		return (a*f(a,b,n-1)+b*f(a,b,n-2))%7;
}
int main()
{
    
    
	while(cin>>a>>b>>n){
    
    
		if(a==0 && b==0 && n==0)
			break;
		cout<<f(a,b,n)<<endl;
	}
	return 0;
}

很快写出来上述代码,就是简单的递归函数,自信的提交竟然是 Memory Limit Exceeded,归根结底就是迭代次数太多了超出了内存限制,代码不够好
在CSDN上翻了翻,发现这是一个有点意思的题,主要是因为有点争议,有些人做出来了却解释不清为什么,我也利用我浅薄的知识探索一下:(看看规律在哪里)

#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
int f(int a,int b,int n)
{
    
    
	if(n==1 || n==2)
		return 1;
    else
		return (a*f(a,b,n-1)+b*f(a,b,n-2))%7;
}
int main()
{
    
    
	int a,b,n;
	while(scanf("%d%d%d",&a,&b,&n) !=EOF){
    
    
		if(a==0 && b==0 && n==0)
			break;
		for(int i=1;i<=n;i++)
			cout<<f(a,b,i);
	}
	return 0;
}

测试时计算机计算起来比较慢:

在这里插入图片描述

不到五十位我就关了,出来的有点慢但是我们确实惊奇地发现还是有规律的(1123160…),16个一循环,至于为什么,应该交给数学家解释,多试几组:
在这里插入图片描述
14个一循环
在这里插入图片描述
这个有点异样了吧。。。。
试到这里,我们先依据网友分享尝试给出’AC‘代码:

#include<iostream>
#include<cstdio>
using namespace std;
int a,b,n,c[100];
int main()
{
    
    
	while(cin>>a>>b>>n){
    
    
		if(a==0 && b==0 && n==0)
			break;
		c[1]=1;
		c[2]=1;
		for(int i=3;i<=48;i++){
    
    
			c[i]=(a*c[i-1]+b*c[i-2])%7;
		}
		cout<<c[n%48]<<endl;
	}
	return 0;
}

过了,但是还没完啊:’
咱们先用前面的代码试一试两个测试样例:(a=1,b=1 的在前面,下面是a=1,b=2的)
在这里插入图片描述

是周期并且周期为6
所以我们得出一个结论:周期是有的,但是不能用48来衡量!我上面的例子一个周期为14,一个从第二位才开始周期,显然就不能用所谓的AC代码解决了,只能说这是一个笑话,杭电的测试用例周期恰好都是48的因数,所以侥幸通过了,要想得到真正正确的答案,得另寻办法:

矩阵快速幂

#include<iostream>
using namespace std;
struct M{
    
    
	int m[2][2];
};
int A,B;
M mul(M a,M b){
    
    
	M ans;
	for(int i=0;i<2;i++){
    
    
		for(int j=0;j<2;j++){
    
    
			ans.m[i][j] = 0;
			for(int k=0;k<2;k++)
				ans.m[i][j] = (ans.m[i][j]+a.m[i][k]*b.m[k][j]%7)%7;
		}
	}
	return ans;
}
M quick(long long b){
    
    
	M ans,c;
	ans.m[0][0] = ans.m[1][1] = 1;
	ans.m[0][1] = ans.m[1][0] = 0;
	c.m[0][0] = A,c.m[0][1] = B,c.m[1][0] = 1,c.m[1][1] = 0;
	while(b){
    
    
		if(b&1) ans = mul(ans,c);
		b >>= 1;
		c = mul(c,c);
	}
	return ans;
}
int main(){
    
    
	long long n;
	while(cin>>A>>B>>n){
    
    
		if(A==0&&B==0&&n==0) break;
		if(n<=2) cout<<"1"<<endl;
		else{
    
    
			M a = quick(n-2);
			cout<<(a.m[0][0]+a.m[0][1])%7<<endl;
		}
	}
}

猜你喜欢

转载自blog.csdn.net/interestingddd/article/details/113870720
今日推荐