算法训练 最大最小公倍数
问题描述
已知一个正整数N,问从1~N中任选出三个数,他们的最小公倍数最大可以为多少。
输入格式
输入一个正整数N。
输出格式
输出一个整数,表示你找到的最小公倍数。
样例输入
9
样例输出
504
数据规模与约定
1 <= N <= 106。
这道题目虽然说是贪心,但是要用到一些数论的东西
算术基本定理可表述为:任何一个大于1的自然数 N,如果N不为质数,那么N可以唯一分解成有限个质数的乘积N=P1a1P2a2P3a3......Pnan,这里P1<P2<P3......<Pn均为质数,其中指数ai是正整数。这样的分解称为 N 的标准分解式。最早证明是由欧几里得给出的。(摘自百度百科)
1.n为奇数时
由算数基本定理可知,相邻的两数之间是互素的
证明如下:
可以看到n除以n-1的各个质因子P1<P2<P3......<Pm 都会余1
同理,n-2和n也是互素的
可以看到n除以n-2的各个质因子(除了2)P1<P2<P3......<Pm 都会余2(特别的,当n除以2时,n是奇数不会被整除)
所以,n为奇数时,(n-2)*(n-1)*n为最优解
2.n为偶数时
相邻两数仍是互素的,但n和n-2就不是互素的,这时就需要遍历找到与n互素且最大的数字,此时求得的结果还需要与(n-1)*(n-2)*(n-3)比较,取最大的
#include<stdio.h>
long long Max(long long a,long long b)
{
return a>b?a:b;
}
long long gcd(long long a,long long b)
{
if(!b)
return a;
else
return gcd(b,a%b);
}
int main()
{
long long n,sum=0;
scanf("%lld",&n);
if(n&1)
{
sum=(n-2)*(n-1)*n;
}
else
{
for(long long i=n-3;i>0;i-=2)
{
if(gcd(i,n)==1)
{
sum=i*(n-1)*n;
break;
}
}
sum=Max(sum,(n-1)*(n-2)*(n-3));
}
printf("%lld",sum);
return 0;
}