51Nod->1419最小公倍数挑战 (数论)

58 篇文章 1 订阅
46 篇文章 0 订阅

传送门: 1419 最小公倍数挑战

几天以前,我学习了最小公倍数。玩得挺久了,想换换口味。

我不想用太多的数字,我想从1到n中选三个数字(可以相同)。使得他们的最小公倍数最大。


Input
单组测试数据。
第一行有一个整数n (1≤n≤1,000,000)。
Output
输出一个整数表示选三个数字的最大的最小公倍数。
Input示例
9
7
Output示例
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时。

好了,至此我们已经分析完了所有情况。

[cpp]  view plain  copy
  1. #include<bits/stdc++.h>  
  2. #define  ll __int64  
  3. using  namespace  std;  
  4.   
  5. int main(){  
  6.   ll n,ans;  
  7.   cin>>n;  
  8.   if(n<3)ans=n;  
  9.   else  if(n%2!=0){  
  10.     ans=n*(n-1)*(n-2);  
  11.   }  
  12.   else{  
  13.     if(n%3!=0)ans=n*(n-1)*(n-3);  
  14.     else ans=(n-1)*(n-2)*(n-3);  
  15.   }  
  16.   cout<<ans<<endl;  
  17.   return 0;  
  18. }  

当然也可以暴力,不过三种循环下界最小不可能小于n-5

[cpp]  view plain  copy
  1. #include <iostream>  
  2.   
  3. using namespace std;  
  4. long long gcd(long long a,long long b){  
  5.     if(b==0)  
  6.     return a;  
  7.     return gcd(b,a%b);  
  8. }  
  9. long long lcm(long long a,long long b){  
  10.     return a/gcd(a,b)*b;  
  11. }  
  12. int main(){  
  13.     long long a[50];  
  14.     long long i,j,k,n,sum;  
  15.     while(cin>>n){  
  16.         if(n==1){  
  17.             cout<<"1"<<endl;  
  18.             continue;  
  19.         }  
  20.         if(n==2){  
  21.             cout<<"2"<<endl;  
  22.             continue;  
  23.         }  
  24.         if(n==3){  
  25.             cout<<"6"<<endl;  
  26.             continue;  
  27.         }  
  28.         sum=-1;  
  29.         for(i=n;i>=n-5;i--)  
  30.         for(j=i-1;j>=n-5;j--)  
  31.         for(k=j-1;k>=n-5;k--)  
  32.         sum=max(sum,lcm(lcm(i,j),k));  
  33.         cout<<sum<<endl;  
  34.     }  
  35.     return 0;  
  36. }  



0
0
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值