题目:
再战斐波那契
题源:https://hpuoj.com/contest/23/problem/A/
单点时限: 1.0 sec
内存限制: 512 MB
小z 学会了斐波那契和 gcd 后,老师又给他出了个难题,求第N个和第M个斐波那契数的最大公约数,这可难倒了小z ,不过在小z 的再三请求下,老师又告诉他了个条件,gcd(N,M)∈[1,90]。
可是,笨拙的小z 还是不会,于是请求你帮他解答这个问题。
已知:
Fibonacci[i]={i,Fibonacci[i−1]+Fibonacci[i−2],i<=1i>1
输入格式
输入包括 T 组,T∈[1,10].
接下来 T 行,每行两个整数 N,M, 表示斐波那契的第 N 项和第 M 项,(N,M∈[1,10的18次方]).
输出格式
输出包含 T 行,每行输出一个整数.
样例
input
3
1 2
2 3
3 4
output
1
1
1
题解:
题意很简单,分别求出两个斐波那契数,然后求它们的最大公约数。问题就在于,这两个斐波那契数太大了,你是求不出来的。你写好程序后要么时间超限,要么内存超限。求不出来的东西必然含有某种规律,通过打表找规律,可以发现斐波那契最大公约数定理:gcd(fib(m),fib(n))=fib(gcd(m,n))。写题的时候注意变量的类型,和输出格式。
Ac代码:
#include <iostream>
#define ll long long //用宏定义来定义long long变量类型,也是很6了
using namespace std;
ll f[10000]; //定义一个斐波那契数组,来存对应的斐波那契数
int gcd(ll a, ll b)
{
return b ? gcd(b, a % b) : a;
}
int main()
{
int t;
ll n, m;
scanf("%d", &t);
f[1] = f[2] = 1; //非递归求斐波那契数,拿个小本本记下来
for(int i = 3; i <= 100; i ++ ) f[i] = f[i - 1] + f[i - 2];
while(t -- )
{
scanf("%lld %lld", &n, &m);
printf("%lld\n",f[gcd(n, m)]); //斐波那契数列最大公约数定理
}
return 0;
}
怎么说呢,这道小小的题其实能反映大大的问题。在知道这道题的答案后,也发现了自己的很多不足。
首先,我看到这道题后天真地以为这是签到题,而那些大佬们直接就先跳过这道题了。
看一下数据范围【1,10的18次方】,这么大的数据范围,一看就应该想到很难求了。
不过事后发现其实如果坚持一下认真找规律还是很好找到的,没找到规律的原因是,一看难就放弃了,不过要是人人一眼都能看出来,那还能拉开啥差距,拼的就是认真和耐心,以后不要懒了,再认真些叭。
还有就是long long 输出的时候是lld,long输出的时候是ld,这些在用printf输出的时候要注意下。