资源限制
时间限制:10.0s 内存限制:256.0MB
问题描述
斐波那契串由下列规则生成:
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。
思路:
这道题如果就是简单的循环是肯定不行的,差不多到30的时候就会报错,所以这道题要取个巧,看一下f(i)的与f(i-1)的区别。以下是我找到的规律:
当s="10110101101101"
可以 发现他的个数也像是一个斐波那契数列,就可以找到规律f(i)=f(i-1)+f(i-2)+1。
代码:
#include<bits/stdc++.h>
using namespace std;
long long n;
long long ans1;
long long ans2;
long long ans;
string s;
string s1 = "0";
string s2 = "1";
string s0;
int main()
{
cin >> n;
cin >> s;
for (int i = 2; i <= 23; i++)//先算到23的s0
{
s0 = s2 + s1;
s1 = s2;
s2 = s0;
}
for (int i = 0; i <= (s0.size() - s.size()); i++)
{
if (s == s0.substr(i, s.size()))
{
ans1++;//当n=23的答案
}
}
s0 = s2 + s1;
s1 = s2;
s2 = s0;
for (int i = 0; i <= (s0.size() - s.size()); i++)
{
if (s == s0.substr(i, s.size()))
{
ans2++;//当n=24的答案
}
}
for (int i = 25; i <= n; i++)//再用找到的规律算到n
{
ans = ans1 + ans2+1;
ans1 = ans2;
ans2 = ans;
}
cout << ans << endl;
return 0;
}