蓝桥杯算法训练 最大最小公倍数

算法训练 最大最小公倍数


问题:

问题描述

已知一个正整数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并未超出范围。
原文地址:https://www.cnblogs.com/neverth/p/11760942.html