问题描述
已知一个正整数N,问从1~N中任选出三个数,他们的最小公倍数最大可以为多少。
输入格式
输入一个正整数N。
输出格式
输出一个整数,表示你找到的最小公倍数。
样例输入
9
样例输出
504
数据规模与约定
1 <= N <= 106。
当时不知道该怎么使用贪心算法,也不知道怎么贪心,因为题目最大的最小公倍数“可能“是多少,我就直接输出n*(n-1)*(n-2),很自然这是最大的,不仅仅是可能,而且一定是,相邻的三个数的最大公约数就是1.但是这样是错误的,后来我就考虑也许在小范围内贪心,任选三个数a,b,c.应该判断a,b和a,c和b,c同时互质,三组数据每两个都互质的情况下才可以。否则就要适当调整。选取数据的时候应该先选取大数。分析发现,当n为奇数的时候,选取n,n-1,n-2满足条件,直接输出就可以了,当n为偶数的情况下,就要调整,调整规则就是是的选取的数a,b,c差距尽可能的小,而且还满足两两互质,就输出a*b*c。
下面的java代码是自己写的,但是不知道为什么只能得到30分!
import java.util.*;
import java.math.*;
class member
{
public long gcd(long mx,long nx)
{
int t;
t=(int)mx%(int)nx;
while(t!=0)
{
mx=nx;
nx=t;
t=(int)mx%(int)nx;
}
return nx;
}
private long lcm(long mx,long nx)
{
return mx*nx/gcd(mx,nx);
}
public long lcm_3(long mx,long nx,long rx)
{
return lcm(lcm(mx,nx),rx);
}
public long gcd_3(int mx,int nx,int rx)
{
return gcd(gcd(mx,nx),rx);
}
}
public class Main
{
public static void main(String[] args)
{
Scanner sc=new Scanner(System.in);
long n=sc.nextInt();
member m=new member();
long k1=n,k2=n-1,k3=n-2;
while(true)
{
if(n<=2)
{
System.out.println(2);
break;
}
if(m.gcd(k1, k3)!=1)
{
if(k1-k3>=3)//3的倍数的时候会使得差距过大,这个时候改k1的值更合适
k1=k3+1;
else
k3--;
}
if(m.gcd(k1, k2)!=1)
k2--;
if(m.gcd(k2, k3)!=1)
k3--;
if((m.gcd(k1, k2)==1)&&(m.gcd(k1, k3)==1)&&(m.gcd(k2, k3)==1))
{
System.out.println(m.lcm_3(k1, k2, k3));
break;
}
}
}
}
下面的C++的是从百度找到的,感觉就是对规律的提炼和简化直接输出,更方便,不知道为什么,人家这个可以得60.我测试了很多数据,也没有找到我的数据和它的不同,似乎每个测试数据输出结果都是一样的,不知道自己的java那里错了。
#include<iostream>
#include<cmath>
using namespace std;
int main()
{
long long n, number;
cin>>n;
if( n <= 2)
{
cout<<2;
}
else if(n % 2)
{
number = n * (n - 1) * (n - 2);
cout<<number;
}
else
{
if( n % 3 == 0)
{
number = (n - 1) * (n - 2) * (n - 3) ;
}
else number = n * (n - 1) * (n - 3);
cout<<number;
}
return 0;
}