蓝桥杯练习系统(算法训练)ALGO-980 斐波那契串

资源限制

内存限制:256.0MB   C/C++时间限制:10.0s   Java时间限制:30.0s   Python时间限制:50.0s

问题描述

  斐波那契串由下列规则生成:
  F[0] = "0";
  F[1] = "1";
  F[n] = F[n-1] + F[n-2] (n≥2,+表示连接)
  给出一个由0和1构成的串S和一个数n,求出F[n]中S出现的次数。

输入格式

  第一行一个数n。
  第二行一个01串S。

输出格式

  答案。

样例输入

96
10110101101101

样例输出

7540113804746346428

数据规模和约定

  n≤263-1,子串长≤10000,答案≤263-1。

暴力,特别暴力的方法,显然是不行的,但是为了方便理解:(n<=30还是可以的,但这里n很大)

#include<iostream>
#include<string>
using namespace std;
int main(){
	long long int n;
	string s1="0",s2="1",s3,s;
	scanf("%d",&n);
	cin>>s;
	for(int i=2;i<=n;i++){
		s3=s1+s2;
		s1=s2;
		s2=s3;
	}
	//求个数
	long long int cnt=0;
	for(int j=0;j<s3.length();j++){
		if(s3.substr(j,s.length())==s){
			cnt++;
		}
	} 
	printf("%lld\n",cnt);
	return 0;
} 

以下是100分的代码:

#include<iostream>
#include<string>
using namespace std;
int flag;
long long int L1,L2,L;//成斐波那契数列的答案,L1为第一个不为0的个数,L2为第2个不为0的个数 
long long int x;//第一个不为0的位置 
int main(){
	long long int n;
	string s1="0",s2="1",s3,s;
	scanf("%lld",&n);
	cin>>s;
	for(int i=2;i<=n;i++){
		s3=s1+s2;
		s1=s2;
		s2=s3;
		for(int j=0;j<s3.length();j++){
			if(s3.substr(j,s.length())==s){
				flag=1;
				break;
			}
		} 
		if(flag==1){
			x=i; 
			break; 
		}
	}
	for(int j=0;j<s3.length();j++){
		if(s3.substr(j,s.length())==s){
			L1++;
		}
	} 
	s3=s1+s2;
	s1=s2;
	s2=s3;
	for(int j=0;j<s3.length();j++){
	if(s3.substr(j,s.length())==s){
			L2++;
		}
	}
	for(int i=x+2;i<=n;i++){
		L=L1+L2+1;//规律
		L1=L2;
		L2=L; 
	}
	printf("%lld\n",L);
	return 0;
} 

 思路:s串的个数成类似于斐波那契数列的规律。

虽然前面提到的暴力方法不能求解n很大的情况,但是前25个绝对没问题,根据暴力方法输出前25个来找规律:

假设串s="10110101101101"

#include<iostream>
#include<string>
using namespace std;
int main(){
	string s1="0",s2="1",s3,s;
	int n;
	scanf("%d",&n);
	cin>>s;
	for(int i=2;i<=n;i++){
		s3=s1+s2;
		//求个数
		int cnt=0;
		for(int j=0;j<s3.length();j++){
			if(s3.substr(j,s.length())==s){
				cnt++;
			}
		} 
		printf("n=%d:%d个\n",i,cnt);
		s1=s2;
		s2=s3;
	}
	
	return 0;
} 

可以发现,从含有串s个数不为0的F[n]之后,如F[7],F[8]之后,有以下规律:

F(i)=F(i-1)+F(i-2)+1 

因此只需找到第一个含s串的位置x,求出个数L1,然后求出位置x+1的个数L2,之后根据规律即可求出所有。

//但是这个规律好像也不大对,当s=“01”时:

第三个数是前两个数的和,不需要+1了。。这个方法还是不太严谨,虽然它通过了吧。希望可以给你带来一些思路,如果有更好的方法欢迎在评论区留言或私信我。

  • 9
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值