题目链接:A——又是斐波那契数列??
A 又是斐波那契数列??
时间限制 内存限制 出题人
1 Second 128 Mb 李战士
题目描述
大家都知道斐波那契数列吧?斐波那契数列的定义是这样的: f0 = 0, f1 = 1, fi = fi−1 + fi−2
现在给你一个数x,聪明的你一定知道这是斐波那契数列中的第几项。
(数据保证x一定有对应的项y,且 2 ≤ y < 1e4)
输入
第一行一个整数T,表示测试组数。
之后的T行,每行一个数x
输出
对于每个测试数据,输出一行表示数x是第几项。
输入样例
2
2
5
输出样例
3
5
题解:大家都知道斐波那契,这么大的数据用 long long int 存也会超了。之前做过一个题目是用循环结解决的,因为除以一个数得到的结果组合有很多种,我想到一个方法是把结果除以一个非常大的素数。把得到的结果存起来,再用for来查找。为了排除会有重复的情况,我用除重查了一下,没有重复的。
查重代码:
#include<bits/stdc++.h>
#define mod 1000000007
using namespace std;
long long int a[10100];
void f()
{
a[0]=0;
a[1]=1;
for(int i=2;i<10100;i++)
{
a[i]=(a[i-1]+a[i-2])%mod;
}
}
int main()
{
f();
sort(a,a+10000);
int sum=unique(a,a+10000)-a;
cout<<sum<<endl;
return 0;
}
//sum=9999
AC代码:
#include<bits/stdc++.h>
#define mod 1000000007
using namespace std;
long long int a[10100];
void f()
{
a[0]=0;
a[1]=1;
for(int i=2;i<10100;i++)
{
a[i]=(a[i-1]+a[i-2])%mod;
}
}
int main()
{
f();
int n;
cin>>n;
while(n--)
{
char s[10000]; //接受的字符可能非常大,用字符串来接受
cin>>s;
long long int ans=0;
int slen=strlen(s);
for(int i=0;i<slen;i++) // 取模
{
ans=ans*10+(s[i]-'0');
ans=ans%mod;
}
for(int i=2;i<10100;i++)
{
if(a[i]==ans)
{
cout<<i<<endl;
break;
}
}
}
return 0;
}
补充:
标称代码当时没看懂,后来有人告诉是利用 ull 的上限自动取模,做法的思路和之前差不多。
经常遇到范围是2^63,取模2^64的这种题目。遇到这种限制条件时就要想到用unsigned long long类型。
可以简洁地声明为typedef unsigned long long ull。这样,如果ull类型的整数溢出了,就相当于取模2^64了。因为ull的范围是[0,2^64-1]。
而ll的范围是[-2^63,2^63-1],因为有符号的第63位表示“正负”而不表示数值。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
const int N = (int) 100000 + 11;
const int M = (int) 1e6 + 11;
const int MOD = (int) 1e9 + 7;
const int INF = (int) 0x3f3f3f3f;
ull f[N]={0,1};
map<ull, int> mp;
int main(){
mp[1] = 1; mp[0] = 0;
for(int i = 2; i < N; i++){
f[i] = f[i-1] + f[i-2];
mp[f[i]] = i;
}
int T; cin>>T;
while(T--){
string s; cin>>s;
ull ans=0;
for(int i = 0; s[i]; i++) ans = (ans * 10 + s[i] - '0');
cout<<mp[ans]<<"\n";
}
return 0;
}