【wikioi】1012 最大公约数和最小公倍数问题

题目链接

算法:辗转相除(欧几里得)

gcd(a, b)是a和b最小公倍数, lcm(a, b)是a和b的最大公倍数

gcd(a, b) == gcd(b, a%b)

时间复杂度: O(lgb)

具体证明很多的,百度即可。

代码:

int gcd(int a, int b){return (b?gcd(b, a%b):a);}

(非递归版自己推)

 

lcm(a, b) = a*b/gcd(a, b)

这里要注意个细节优化,在程序中应该防止溢出,即要写成

lcm(a, b) = a/gcd(a, b)*b

时间复杂度:O(lgb)

代码:

inline int lcm(int a, int b){return a / gcd(a, b) * b;}

好了到此题:【wikioi】1012

14.01.02 PS: 这是之前的代码,有点不简洁。

一般枚举算法

//暴力枚举即可

//只不过gcd(a, b) == gcd(b, a%b); lcm(a, b) == a/gcd(a, b)*b;

#include <iostream>

using namespace std;



int mymin, mymax;

void gcd(const int &a, const int &b){if(a%b==0) mymin=b; else gcd(b, a%b);}

inline int lcm(const int &a, const int &b){return (a/mymin)*b;}



int main()

{

    int tmin, tmax;

    cin >> tmin >> tmax;

    int ans = 0;

    for(int i = tmin; i <= tmax; i++)

    {

        if(i % tmin != 0 || tmax % i != 0) continue;

        for(int j = tmin; j <= tmax; j++)

        {

            if(j % tmin != 0 || i * j < tmax || tmax % j != 0) continue;

            gcd(i,j);

            if(mymin != tmin) continue;

            mymax = lcm(i, j);

            if(mymax != tmax) continue;

        	ans++;

        }

    }

    cout << ans << endl;

    return 0;

}

你可能感兴趣的:(IO)