题目链接:https://cn.vjudge.net/problem/UVA-10791
题目大意:输入整数n,求至少两个正整数,使得他们的最小公倍数为n,且这些整数的和最小,输出最小的和。
题意分析:求至少两个正整数,使得他们的最小公倍数为n,我们使用到唯一分解定律。n=p1^t1+p2^t2+..pr^tr
我们可以发现当因子个数最多时,这些因子相加和最小(比如:12=3*4 12>3+4)
所以我们只需分解n,把这些素数相加就可以
1 #include<iostream> 2 #include<algorithm> 3 #include<cmath> 4 using namespace std; 5 long long solve(int n) 6 { 7 long long ans=0; 8 int t=0; 9 int h=sqrt(n+1); 10 int temp=1; 11 for(int i=2;i<=h;i++) 12 { 13 if(n%i==0) 14 { 15 t++,temp=1; 16 while(n%i==0) 17 { 18 n/=i; 19 temp*=i;//注明:ans+=i;这是2*3,像用temp*=i,才是2^3 20 } 21 ans+=temp; 22 } 23 } 24 if(n>1)//有大于sqrt(n)的素数因子 25 ans+=n,t++; 26 if(t==1)//t表示素数因子的个数 ,题中要求至少2个数 27 ans+=1; 28 return ans; 29 } 30 int main() 31 { 32 // freopen("D:\\in.txt","r",stdin); 33 // freopen("D:\\out.txt","w",stdout); 34 int n,t=1; 35 while(~scanf("%d",&n)) 36 { 37 if(n==0) 38 break; 39 if(n==1) 40 printf("Case %d: 2\n",t++); 41 else 42 printf("Case %d: %lld\n",t++,solve(n)); 43 } 44 // fclose(stdin); 45 //fclose(stdout); 46 }
注意事项:
1.注意n=1,答案是2,想这种边界都需要测试一下
2.区别两者的区别,一个是起到乘的作用,一个是加(不符合题目要求,可拿8模拟)
1 if(n%i==0) 2 { 3 t++,temp=1; 4 while(n%i==0) 5 { 6 n/=i; 7 temp*=i;//注明:ans+=i;这是2*3,像用temp*=i,才是2^3 8 } 9 ans+=temp; 10 }
1 if(n%i==0) 2 { 3 t++,temp=1; 4 while(n%i==0) 5 { 6 n/=i; 7 ans+=i;//注明:ans+=i;这是2*3,像用temp*=i,才是2^3 8 } 9 }
#include<iostream> #include<algorithm> #include<cmath> using namespace std; long long solve(int n) { long long ans=0; int t=0; int h=sqrt(n+1); int temp=1; for(int i=2;i<=h;i++) { if(n%i==0) { t++,temp=1; while(n%i==0) { n/=i; temp*=i; } ans+=temp; } } if(n>1||t==0)//有大于sqrt(n)的素数因子 ans+=n,t++; if(t==1)//t表示素数因子的个数 ,题中要求至少2个数 ans+=1; return ans; } int main() { // freopen("D:\\in.txt","r",stdin); // freopen("D:\\out.txt","w",stdout); int n,t=1; while(~scanf("%d",&n)) { if(n==0) break; cout<<"Case "<<t++<<": "<<solve(n)<<endl; } // fclose(stdin); //fclose(stdout); }