题目描述
对于Fibonacci数列:1,1,2,3,5,8,13......大家应该很熟悉吧~~~但是现在hanzhoufeng有一个很“简单”问题:第n项和第m项的最大公约数是多少?但是hanzhoufeng数学太烂了,只好去问上任数学课代表么么虫....但是么么虫也不会,只好来请教你了......
输入格式
两个正整数n和m。(n,m<=10^9)
输出格式
Fn和Fm的最大公约数。
由于hanzhoufeng看了大数字就头晕,所以只要输出最后的8位数字就可以了。
这个题数据范围极大,若是硬做根本不行
一开始的代码:
#include<bits/stdc++.h>
using namespace std;
inline double s(long double a,long long b)
{
if(b==0)return 1;
double k=s(a,b/2);
if(b%2==0)
return k*k;
else
return k*k*a;
}
long double m=(1+double(sqrt(5)))/2;
long double k=(1-double(sqrt(5)))/2;
inline int f(long long n)
{
if(n==1)return 1;
return (abs(s(m,n)-s(k,n)))*1.0/double(sqrt(5));
}
inline int gcd(long long m,long long n)
{
return n==0?m:gcd(n,m%n);
}
int main()
{
long long m1,n1,a[100000],t=0;
cin>>m1>>n1;
long long m1p=f(m1);
long long m2p=f(n1);
long long ans1=gcd(m1p,m2p);
//输出后八位
//cout<<m1p<<" "<<m2p<<endl;
if(ans1<100000000)
cout<<ans1;
else
{
while(ans1)
{
a[++t]=ans1%10;
ans1/=10;
}
for(int i=t;i>=1;i--)
{
cout<<a[i];
}
}
}
很显然m,n为20/30以上时就超出数据范围。
有一个重要结论:
gcd(fn,fm)=f(gcd(n,m))
既第n项第m项的公倍数==第n和m的公倍数那一项的数字项
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
long long n,m,a[1000000],uke;
int main()
{
cin>>n>>m;
uke=__gcd(n,m);//__gcd为编译器自带的求最大公约数的函数
for(int i=1;i<=uke;i++)
{
if(i==1||i==2)//其实可以打表的对吧,设置数列前两项为1
{
a[i]=1;
continue;
}
a[i]=(a[i-1]+a[i-2])%100000000;//取后8位,题目的要求
}
cout<<a[uke]<<endl;
}