资源限制
内存限制: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。
首先,不得不吐槽这道题的表述让我理解了好久,而且我个人认为这个F[n]并不是一个斐波那契串,好了吐槽完毕,开始题解:不难看出F[n]以及由0和1构成的串S都指向了二进制,我们不妨按题目所说的将F[n]的前几项写出来看看有什么规律,下面的表格根据题意F[n] = F[n-1] + F[n-2] (n≥2,+表示连接)写出了F[0]~F[7],现在假设S是"01"(表格中黑体标出)
F[n] | S出现次数 | |
F[0] | "0" | 0 |
F[1] | "1" | 0 |
F[2] | "01" | 1 |
F[3] | "101" | 1 |
F[4] | "01101" | 2 |
F[5] | "10101101" | 3 |
F[6] | "0110110101101" | 5 |
F[7] | "101011010110110101101" | 8 |
这时候我们可以惊奇的发现从S出现开始,S在F[n]中出现的次数就是一个斐波那契串,所以我们只需要找到S第一次出现的位置i,然后计算斐波那契串前n-i项的和即可,代码如下:
n=int(input())
s=input()
sum=0
a,b,i='0','1',0
# 获取S第一次出现位置i
for i in range(n):
a,b=b,a+b
if s in a:
break
a,b=0,1
# 计算斐波那契串前n-i项的和
for i in range(i,n):
a, b = b, a + b
sum+=a
print(sum)