Sweety

Practice makes perfect

导航

蓝桥-最大最小公倍数(互质) (贪心)

Posted on 2015-01-26 23:55  蓝空  阅读(250)  评论(0编辑  收藏  举报

没想到这道题还需要不少的基础知识啊,数论(互质)还有一点不正宗的贪心

这道题是说从1~N中任选出三个数,求出他们的最小公倍数最大为多少,感觉有点生疏,对数论还有单陌生、、、

求出三个数的最小公倍数,运用贪心的原则,使每一步都是最大的,怎么才能达到每一步,也就是首先两个需要公倍数最大,也就是,对,就是这两个是互质的,从而步步贪心,得出三个数中是两两互质的,因此,在这里有必要对互质了解一下。

定义:公约数只有1的两个数,叫做互质数。(1既不是质数也不是合数)

显然仅靠定义是解决不掉互质的判断的,需要推论,也就是数论的一些东西作为引导。

结论:

(1)两个不相同质数一定是互质数。 例如,2与7、13与19。

 (2)相邻的两个自然数是互质数。如 15与 16。

(3)相邻的两个奇数是互质数。如 49与 51。

(5)1不是质数也不是合数,它和任何一个自然数在一起都是互质数。如1和9908。

(4)一个质数如果不能整除另一个合数,这两个数为互质数(即小数是质数,大数不是小数的倍数的两个数是互质数)。如 7和 16、3与10、5与 26。

(6)大数是质数的两个数是互质数。如97与88。

(8)两个数都是合数(二数差又较大),小数所有的质因数,都不是大数的约数,这两个数是互质数。 如357与715,357=3×7×17,而3、7和17都不是715的约数,这两个数为互质数。

(9)两个数都是合数(二数差较小),这两个数的差的所有质因数都不是小数的约数,这两个数是互质数。如85和78。 85-78=7,7不是78的约数,这两个数是互质数。

(10)两个数都是合数,大数除以小数的余数(不为“0”且大于“ 1”)的所有质因数,都不是小数的约数,这两个数是互质数。如 462与 221 462÷221=2……20, 20=2×2×5。 2、5都不是221的约数,这两个数是互质数。 (这好像是求最大公约数方法的一个特例,也就是他们的最小公约数为1了

(11)减除法。如255与182。 255-182=73,观察知 73182。 182-(73×2)=36,显然 3673。 73-(36×2)=1, (255,182)=1。 所以这两个数是互质数。 三个或三个以上自然数互质有两种不同的情况:一种是这些成互质数的自然数是两两互质的。如2、3、4。另一种不是两两互质的。如6、8、9。(辗转相除术?)

至于本题好像用的相对推导的东西稍多,需要基本分四种情况讨论,这里借鉴一下篇解释的很好的博客。

思路:若n 和 n-1和n-2 三个数 两两互质的话,那么结果就是这三个数的积。

根据数论知识:任意大于1的两个相邻的自然数都是互质的.

我们可以知道,当n是奇数时,n 和n-2都是奇数,n-1是偶数,那么他们三个的公约数肯定不是2,而因为这三个数是连续的,所以大于2的数都不可能成为他们或其中任意两个数的公约数了.结果就是他们三个的乘积.

而当n为偶数时,n*(n-1)*(n-2)肯定不行了,因为n和n-2都是偶数,那么只能将n-2改成n-3,即n*(n-1)*(n-3),如果这三个数两两互质那么肯定就是结果了.

但是因为n和n-3相差3,所以当其中一个数能被3整除时,另一个肯定也可以.而当其中一个不可以时,另一个肯定也不可以.而因为n为偶数,n-3为奇数,所以2不可能成为他俩的公因子。对于大于3的数,肯定就都不可能成为这三个数或者其中任意两个数的公约数了.因此只需再对3进行判断:

如果n能整除3,那么,n*(n-1)*(n-3)就肯定不行了,因为n和n-3有了公约数3,结果肯定小了,那么就只能继续判下一个即n*(n-1)*(n-4)而这样n-4又是偶数,不行继续下一个n*(n-1)*(n-5) = n^3 -6*n^2 + 5*n 而如果这个可以 那个其值肯定要小于(n-1)*(n-2)*(n-3) = n^3 -6*n^2+11n-6(对于n>1来说都成立),而(n-1)*(n-2)*(n-3)由上一个奇数结论可知是一个符合要求的,因此到n-5就不用判断了。直接选答案为(n-1)*(n-2)*(n-3);

而n不能整除3,那么结果就是n*(n-1)*(n-3),因为n和n-3都不能整除3,此时n-1能不能整除3都无关紧要了.而对于其它数 都是不可能的.上面已证.

点击网址


实现代码:

#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <cstring>
#include <algorithm>  
#include <iostream>
using namespace std;
int main(){
    long long ans, n;
    while(cin >> n){
            if(n<=2)  ans = n;
            else
			  if(n%2) ans = n*(n-1)*(n-2);//n为奇数 
              else //n为偶数 
                if(n%3)ans = n*(n-1)*(n-3);   
                else ans = (n-3)*(n-1)*(n-2);
            cout<<ans<<endl;
    }
    return 0;
}


不过只能过60%,好像是后台的数据有问题,感觉推导挺对的。。。