算法训练 最大最小公倍数
问题:
问题描述
已知一个正整数N,问从1~N中任选出三个数,他们的最小公倍数最大可以为多少。
输入格式
输入一个正整数N。
输出格式
输出一个整数,表示你找到的最小公倍数。
样例输入
9
样例输出
504
数据规模与约定
1 <= N <= 10^6。
这道题在想的时候就想到用常规办法来写,但是写到一半发现套用了4层循环,在回过头来看一下,数据规模最大为10的6次方。常规方法肯定是不行的,但是我还是用常规办法写了出来想测试一下,下面这串代码在N为500以内还是能算出来的。但是放在蓝桥杯里面全部都是运行超时。
//运行超时,不可行
#include <iostream>
using namespace std;
int main() {
int N, temp = 0, temp1 = 0, temp2 = 0, temp3 = 0;
cin >> N;
for (int i = 1; i <= N; ++i) {
for (int j = i + 1; j <= N; ++j) {
for (int k = j + 1; k <= N; ++k) {
for (int z = 1; z <= i; z++) {
if (i % z == 0 && j % z == 0)
temp = z;
}
if (i * j / temp > temp1)
temp1 = i * j / temp;
for (int z = 1; z <= (temp1 > k ? k : temp1); z++) {
if (temp1 % z == 0 && k % z == 0)
temp2 = z;
}
if (temp1 * k / temp2 > temp3)
temp3 = temp1 * k / temp2;
}
}
}
cout << temp3 << endl;
system("pause");
return 0;
}
需要了解:
判断互质数的五种方法:(引用用此处)
一. 概念判断法
公约数只有1的两个数叫做互质数。根据互质数的概念可以对一组数是否互质进行判断。如:9和11的公约数只有1,则它们是互质数。
二. 规律判断法
根据互质数的定义,可总结出一些规律,利用这些规律能迅速判断一组数是否互质。
(1)两个不相同的质数一定是互质数。如:7和11、17和31是互质数。
(2)两个连续的自然数一定是互质数。如:4和5、13和14是互质数。
(3)相邻的两个奇数一定是互质数。如:5和7、75和77是互质数。
(4)1和其他所有的自然数一定是互质数。如:1和4、1和13是互质数。
(5)两个数中的较大一个是质数,这两个数一定是互质数。如:3和19、16和97是互质数。
(6)两个数中的较小一个是质数,而较大数是合数且不是较小数的倍数,这两个数一定是互质数。如:2和15、7和54是互质数。
(7)较大数比较小数的2倍多1或少1,这两个数一定是互质数。如:13和27、13和25是互质数。
三. 分解判断法
如果两个数都是合数,可先将两个数分别分解质因数,再看两个数是否含有相同的质因数。如果没有,这两个数是互质数。如:130和231,先将它们分解质因数:130=2×5×13,231=3×7×11。分解后,发现它们没有相同的质因数,则130和231是互质数。
四. 求差判断法
如果两个数相差不大,可先求出它们的差,再看差与其中较小数是否互质。如果互质,则原来两个数一定是互质数。如:194和201,先求出它们的差,201-194=7,因7和194互质,则194和201是互质数。
五. 求商判断法
用大数除以小数,如果除得的余数与其中较小数互质,则原来两个数是互质数。如:317和52,317÷52=6……5,因余数5与52互质,则317和52是互质数。
题目分析:
找出三个互质的最大数,直接相乘就得到了最大的最小公倍数,从上面可以看出两个连续的自然数一定是互质数、相邻的两个奇数一定是互质数,
- 因此因此当N为奇数时,最大最小公倍数为N*(N-1) *(N-2)
上面这种是奇数情况下,那偶数情况下呢,要满足三个数都为互质数可以将三个数前移,即 (N-1)(N-2)(N-3),
这时又符合当N为奇数时的情况,但是并不能保证此时最大,
因为还有 N*(N-1)(N-3) 这种明显看起来比 (N-1)(N-2)*(N-3)的情况大,更加符合条件,但是这种并不能完全保证三个数互质,那什么情况下能保证互质呢?
当为 N*(N-1)*(N-3)。 此时N跨越了3的循环,如果说他们不互质的话那么唯一的可能约数就是3了,所以这里只要判断是N是否是3的倍数即可如果是3的倍数的话,那么(N-1) * (N-2) * (N-3)明显要大,而N * (N-1)* (N-3)并不互质。若是n不是3的倍数,则N* (N-1)* (N-3)大,从上面我们就可以分析出
- 当N为偶数时,如果N % 3 == 0,那么(N-1) * (N-2) * (N-3)
- 当N为偶数时,如果N % 3 != 0,那么N * (N-1) * (N-3)
代码:
#include <iostream>
using namespace std;
int main() {
long long N, ans;
cin >> N;
if (N <= 2)
ans = N;
else if(N % 2 == 1)
ans = N * (N - 1) * (N - 2);
else {
if (N % 3 == 0)
ans = (N - 1) * (N - 2) * (N - 3);
else
ans = N * (N - 1) * (N - 3);
}
cout << ans << endl;
system("pause");
return 0;
}
对于我:
- 一些数的规律和带特殊属性的数都是常考的内容
- 对于上面的代码,假如把long long N, ans;分开,改成int N;long long ans;就会出错,此时输入的N并未超出范围。