传送门: 1419 最小公倍数挑战
几天以前,我学习了最小公倍数。玩得挺久了,想换换口味。
我不想用太多的数字,我想从1到n中选三个数字(可以相同)。使得他们的最小公倍数最大。
单组测试数据。 第一行有一个整数n (1≤n≤1,000,000)。
输出一个整数表示选三个数字的最大的最小公倍数。
9 7
504 210
现在开始分析:很显然题目中的“(可以相同)”是对n<3情况的特殊说明,因为显然你取任意一个其他数都不会比你取相同的数的结果来的更小。
对于n>=3我们继续分析,问题实质上是要找3个尽可能大的互质的数,显然不互质的数可以将其中之一除去公约数来转变成互质的情况,举几个例子试试你就会发现,当n为奇数时答案似乎就是n*(n-1)*(n-2),为什么呢?让我们来证明下。
证明:首先,任意相邻两数互质,然后只需要证明奇数n和n-2互质即可。
假设n和n-2不互质,那么他们都能表示为p*k和p*k'的形式。(p为最大公约数)
n-(n-2)=p*k-p*k'==>p*(k-k')=2
这说明他们的最大公约数要么是1(那不就是互质吗?)要么是2(或许你可以发表一篇论文找到了2个奇数的最大公约数是2)
显然这是矛盾的,因此奇数n和n-2互质
那么对于偶数来说答案是多少呢?n*(n-1)*(n-3)吗?(想一想为什么)
我们随便找了几个例子一试发现不对,比如当n=18时,因为n和n-3不一定互质,那么答案是n*(n-1)*(n-5)吗?
不一定!就以n=18为例,18*17*13<17*16*15,比起n*(n-1)*(n-5)来说(n-1)*(n-2)*(n-3)是一组更优解(想一想为什么?提示:1、证明互质2、证明比前者值更大)
那么n和n-3什么时候不互质呢,相信我们聪明的读者已经看出来了~没错就是当n%3==0时。
好了,至此我们已经分析完了所有情况。
#include<bits/stdc++.h>
#define ll __int64
using namespace std;
int main(){
ll n,ans;
cin>>n;
if(n<3)ans=n;
else if(n%2!=0){
ans=n*(n-1)*(n-2);
}
else{
if(n%3!=0)ans=n*(n-1)*(n-3);
else ans=(n-1)*(n-2)*(n-3);
}
cout<<ans<<endl;
return 0;
}
当然也可以暴力,不过三种循环下界最小不可能小于n-5
#include <iostream>
using namespace std;
long long gcd(long long a,long long b){
if(b==0)
return a;
return gcd(b,a%b);
}
long long lcm(long long a,long long b){
return a/gcd(a,b)*b;
}
int main(){
long long a[50];
long long i,j,k,n,sum;
while(cin>>n){
if(n==1){
cout<<"1"<<endl;
continue;
}
if(n==2){
cout<<"2"<<endl;
continue;
}
if(n==3){
cout<<"6"<<endl;
continue;
}
sum=-1;
for(i=n;i>=n-5;i--)
for(j=i-1;j>=n-5;j--)
for(k=j-1;k>=n-5;k--)
sum=max(sum,lcm(lcm(i,j),k));
cout<<sum<<endl;
}
return 0;
}