UVA10791
思路:分解质因数。
分解质因数后答案就是各个质因数(次方)的和;
假设两个数a,b,最小公倍数是a*b/gcd(a,b);那么他们的和为a+b,那么a/gcd(a,b)(假设a/gcd(a,b)是那个与另一个数互质 的数 ),和b的最小公倍数也和a,b相同,然后他们是互质的,那么他们的和明显小。
所以当一个数,我们把它分解为a1^x1+a2^x2+a3^x3...,那么我们知到a1^x1,a2^x2..这些数的最小公倍数是n,然后各个互质,我们可以知道a1^x1,a2^x2,可以的到最小公倍数c1,并且a1^x1+a2^x2是最小的,同时这个公倍数与下面的数互质,然后再与下项求,。。。。。一直到最后都是最优的 。
1 #include<stdio.h> 2 #include<algorithm> 3 #include<stdlib.h> 4 #include<iostream> 5 #include<queue> 6 #include<math.h> 7 #include<map> 8 #include<vector> 9 #include<string.h> 10 typedef long long LL; 11 using namespace std; 12 bool prime[100000]; 13 int ans[100000]; 14 int main(void) 15 { 16 int i,j; 17 for(i = 2; i < 1000; i++) 18 { 19 if(!prime[i]) 20 { 21 for(j = i; (i*j) <= 100000; j++) 22 { 23 prime[i*j] = true; 24 } 25 } 26 } 27 int cn = 0; 28 for(i = 2; i < 100000; i++) 29 { 30 if(!prime[i]) 31 { 32 ans[cn++] = i; 33 } 34 } 35 int __ca = 0; 36 int n; 37 int ak = 1; 38 int flag = 0;int p = 0; 39 while(scanf("%d",&n),n!=0) 40 { LL sum = 0;int m = n; 41 int f = 0;ak = 1;flag = 0; 42 p = 0; 43 while(n > 1) 44 { 45 while(n%ans[f]==0) 46 { if(flag == 0)p++; 47 flag = 1; 48 ak*=ans[f]; 49 n/=ans[f]; 50 } 51 if(flag) sum += ak; 52 flag = 0; 53 f++;ak = 1; 54 if((LL)ans[f]*(LL)ans[f] > n) 55 break; 56 } 57 if(n > 1) 58 { 59 p++; 60 sum += n; 61 }if(m==1)sum = 2; 62 printf("Case %d: ",++__ca); 63 if(p==1)sum+=1; 64 printf("%lld\n",sum); 65 } 66 return 0; 67 }
油!油!you@