【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;
}
上一篇:Python创建自己的训练测试两用数据集Dataset类


下一篇:django模型中的抽象类(abstract)