28行代码AC——Minimum Sum LCM UVA - 10791(最大质因子)
勵志用盡量少的代碼做高效表達
題目(提交)鏈接——>UVA - 10791
題意
輸入正整數n,找至少兩個數,使得他們的最小公倍數(Least Common Multiple)為n且要輸出最小的和。
心路歷程
最近在備考藍橋杯, 將本題納入分解質因子專題。
接連刷了一下午的題, 腦瓜子嗡嗡的,看這道題時連題意都沒讀懂就稀里糊涂的開始敲了,WA,后又讀題,調試一小時,成功AC。
首先假設我們知道了一系列數字a1,a2,a3……an,他們的LCM是n,那么什么時候他們是最優解呢,當他們兩兩互質的時候
為了方便我們以兩個數來說明問題。
a和b的LCM是n,GCD是m,那么n=a/m*b , 它們的和就是sum=a+b;
如果m不為1(即a和b不互質),那么我們為什么不優化一下,將a變為a=a/m呢?,改變后a和b的LCM依然是n,但是他們的和顯然減少了
所以我們得到最重要的一個性質,要想a1,a2,a3……an的和最小,要保證他們兩兩互質,只要存在不互質的兩個數,就一定可以近一步優化
那我們怎么保證兩兩互質呢?方法其實很簡單,直接分解質因子
例如24=222*3 , 只能分解為8和3,因為這里有3個2,這3個2必須在一起,如果分開了這3個2,這出現有兩個數會有一個公共的質因子2,并且會使這兩個數的LCM不是24
再例如72=22233,只能分為8和9,因為3個2和2個3都不能分開,他們必須在一次
所以,我們將一個數n分解為質因子后,順便做一個處理,在除干凈一個質因子的同時,將他們乘起來作為一個因子,處理完后會得到多個因子,他們之間同樣滿足兩兩互質的性質
然后是進一步的分析
例如264600=82725*49 , 只是由3個2,3個3,2個5,2個7,處理后得到的因子,那么8,27,25,49的LCM是264600,并且兩兩互質,他們還要不要處理呢?不需要了,直接將他們加起來就是我們要的答案!為什么呢?可以將8,27,25,49這些數字乘起來,無論怎樣乘都好,最后得到的數字它們的LCM依然是n,但是乘起來再相加顯然比直接相加要大得多!
所以我們已經得到了這個問題的解法
1.將一個數分解成質因子,將相同的因子乘起來作為一個處理后的因子
2.將處理后得到的多個因子直接相加就是答案
3.因為題目說只要需要兩個數字,所以對于1和素數我們需要小心。對于素數,我們只能分解出一個因子就它自己,對于1一個因子都分解不出來(我們不把1當做因子),他們的答案都是n+1,因為只有1和n的LCM是n
注意:
1、當n=2^31-1時為素數,輸出結果時需+1,而這個量級在int型變量會溢出,因此改為long long
2、由于本題涉及到本身為因子的情況,但從1遍歷到n顯然太臃腫,因此可以考慮從1遍歷到sqrt(n),最后對n做特殊判斷。
代碼展示
#include<bits/stdc++.h> using namespace std;int Prime_Factor(long long n) {long long sum=0; if(n==1) return 1;long long num = n/2; for(long long i = 2; i*i <= n; i++) {if(n%i==0) {long long sum1=1;while(n%i==0) {sum1 *= i; n /= i;}sum += sum1;}}if(n!=1) sum += n; //n等于1代表全除盡了 return sum; }int main() {int T=0;long long n; while(cin>>n && n) {printf("Case %d: %", ++T);long long sum = Prime_Factor(n);if(sum==n) sum += 1;cout << sum<< endl;} return 0; }歡迎在評論區留言。 如果這篇文章對你產生了幫助,就請給博主一個贊吧!大家的點贊是我創作的最大動力!
總結
以上是生活随笔為你收集整理的28行代码AC——Minimum Sum LCM UVA - 10791(最大质因子)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 辗转相除法(欧几里得算法)求 最大公
- 下一篇: 判断一个数是否是素数,为什么只要除到根号