题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1797
1,求两个数的最大公约数用辗转相除法,求多个数的最大公约数可以先求两个数的最大公约数,用结果去与第三个数求最大公约数,直到结束。
2,求两个数的最小公倍数可以用辗转相除法求出两个数的最大公约数然后用两个数的积除以它就可以得到了,求多个数的最小公倍数,先求前两个数的最小公倍数,得到结果再和第三个数求最小公倍数,直到结束。
3,明白了下面的疑问:用辗转相除法求最小公倍数时要注意应该用a/y*b,若用a*b/y,则可能会数据溢出。
这个题总共做了两个版本:
版本一需要内存较大
#include <iostream>
#include <vector>
using namespace std;
unsigned gcd(unsigned m,unsigned n)
{
unsigned t;
while(n != 0)
{
t = m % n;
m = n;
n = t;
}
return m;
}
int main()
{
freopen("in.txt","r",stdin);
vector<unsigned> v;
v.reserve(100);
int time,count,i;
unsigned res,tmp;
cin >> time;
while(time--)
{
cin >> count;
for(i = 0;i < count;++i)
{
cin >> tmp;
v.push_back(tmp);
}
res = v[0];
for(i = 1;i < count;++i)
res = res / gcd(res,v[i]) * v[i];//有一事不明,v[i]乘到前面就是WA
cout << res << endl;
v.clear();
}
return 0;
}
第二个版本需要内存较小,代码也较简单
#include <iostream>
using namespace std;
unsigned gcd(unsigned m,unsigned n)
{
unsigned tmp;
while(n != 0)
{
tmp = m % n;
m = n;
n = tmp;
}
return m;
}
int main()
{
freopen("in.txt","r",stdin);
unsigned i,x,res,count,time;
cin >> time;
while(time--)
{
cin >> count;
cin >> res;
for(i = 1;i < count;++i)
{
cin >> x;
res = res / gcd(res,x) * x; //有一事不明,x乘到前面就是WA
}
cout << res << endl;
}
return 0;
}
顺便写了一个求多个数最大公约数的算法
#include <iostream>
using namespace std;
unsigned gcd(unsigned m,unsigned n)
{
unsigned t;
while(n != 0)
{
t = m % n;
m = n;
n = t;
}
return m;
}
int main()
{
freopen("in.txt","r",stdin);
int i,time,count;
unsigned x,res;
cin >> time;
while(time--)
{
cin >>count;
cin >> res;
for(i = 1;i < count;++i)
{
cin >> x;
res = gcd(res,x);
}
cout << res << endl;
}
return 0;
}