最大最小公倍数
环境:Dev-C++ 5.9.2
编译器:TDM-GCC 4.8.1
问题描述
已知一个正整数N,问从1~N中任选出三个数,他们的最小公倍数最大可以为多少。
输入格式
输入一个正整数N。
输出格式
输出一个整数,表示你找到的最小公倍数。
样例输入
9
样例输出
504
数据规模与约定
1 <= N <= 106。
#include<iostream>
#include<algorithm>
#include<string>
#include<cmath>
using namespace std;
bool ispn(int a, int b)
{
if(a==1||b==1) // 两个正整数中,只有其中一个数值为1,两个正整数为互质数
return true;
while(1)
{
int t = a%b; // 求出两个正整数的最大公约数
if(t == 0)
{
break;
}
else
{
a = b;
b = t; // 辗转相除
}
}
if(b>1) return false;// 如果最大公约数大于1,表示两个正整数不互质
else return true; // 如果最大公约数等于1,表示两个正整数互质
}
int main()
{
long long int n,res;
cin>>n;
if(n%2)// 如果n是奇数
res=(n)*(n-1)*(n-2);// 最大的值应是连续的3个数 n(奇数)、n-1(偶数)、n-2(奇数)
else // 如果n是偶数
{
if (n%3) // 如果n是偶数且n不是3的倍数
res=(n-1)*(n)*(n-3); //最大值应是n(偶数)、n-1(最大的奇数)、n-3(次大的奇数)
else // 如果n是偶数且是3的倍数
res=(n-1)*(n-2)*(n-3); //最大的三个数n n-1 n-2(与n不互质) 再减一n-3(与n不互质),此时不能再减第三个数了,直接n减一(n-1),即为n-1 n-2 n-3
}
cout<<res<<endl;
return 0;
}
[总结]:解决此题的关键最后还是得靠数学知识- -!,想法主要是取3个最大的数相乘(贪心法的特征),前提是三个数两两互质,然后想到奇数偶数奇数这种形式,然后当n是奇数时,那就是连续的三个数n ,n-1,n-2相乘 为最大。若是偶数,则要考虑到n-2 与n有2这个约数问题,一般自然而然会再对n-2减一,此时就会陷入另一个问题,那就是当n不能被3整除时此时n,n-1,n-3,的确是最大的,但当n能被3整除时,n-3与n就有3这个约数,此时不能再对n-3减一了,因为再减一就变成n-4与n-2就会存在2这个约数,n-5可能与尾数为0的偶数有因子,n-6与n有约数,n-7可能行,但此时三个数变成n,n-1,n-7,有这么容易一直减下去吗???(代码中的ispn函数判断两个数是否互质其实就是做到了-7(最坏情况))例如300,如果老想着对第三个数操作就会变成300,299,293这样,此时却不是最大的。此时就应该想到不能再对第三个数进行操作了,此时若应对n进行减一操作,把n变成n-1,这样n-2也能加入,n-3也能加入,又变成连续的3个数了,299,298,927这三个数确实比300,299,293的乘积大!感觉像在考小学奥数- -!