暑假训练4之斐波那契公约数变式

题目描述

对于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;
}

 

猜你喜欢

转载自blog.csdn.net/lanshan1111/article/details/81288826