没想到这道题还需要不少的基础知识啊,数论(互质)还有一点不正宗的贪心
这道题是说从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%,好像是后台的数据有问题,感觉推导挺对的。。。