HPUACM暑期集训第二次积分训练赛 A——又是斐波那契数列??

题目链接: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;
}

猜你喜欢

转载自blog.csdn.net/qq_40727946/article/details/81282902
今日推荐