http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1732
题目大意:
输入正整数n,(n<=2^31-1),找到至少两个正整数,使得它们的LCM(最小公倍数)为n,并且和最小。
思路:
分解质因子,把各个质因子的相应次方加起来就是答案。
(下面摘自http://blog.csdn.net/xuruoxin/article/details/8847987 首先题意是把多个数的最小公倍数为N的数相加和最小即为答案,注意不是2个,一开始想当然的以为求出所有素数次方分2半求最小和。 这里是素数次方和,也就是pn^nn的和 这样既然是多个数,多少个数的时候最小呢? a * b > a+ b (a, b > 2) 这是必然的吧 。 所以只要把没中素数的n次方相加就行了。 为什么这样可以呢,证明下:
如果不是这样的,n个数相加,其中有2个数享有同一种n的素数,那求最小公倍数的是是可以约去的。。。比如 4, 6 的最小公倍数是12 然而, 4和6都有2为公约数,所以可以约去后再相乘就是最小公倍数了,所以不能同时享有,则可以把 6中的2除去,也就是6/2=3 又 3 和 4的最小公倍数是12. 这里也不能除以4里的2, 这很明显,如果除的话,要不断的除直到4 变为1 而 1和6最小公倍数就是6了。。为什么会这样呢? 因为4是由2^2 构成的 而6是2*3 所以。。也就是说同一种N的素数次方构成的为一个数之后求和)
注意的是直接2到n会TLE
2^31-1=2147483647为素数,要用long long 来存,
n为素数答案为n+1,
当只有单质因子时,答案为质因子相应次方+1;
#include<cstdio>
typedef long long LL;
int main()
{
LL n,kase=1;
while(~scanf("%lld",&n),n)
{
LL ans=0,cnt=0,x=n;
for(LL i=2;i*i<=n;i++)
{
LL temp=1;
if(n%i==0)
{ cnt++;
while(n % i==0)
{
n/=i;
temp*=i;
}
ans+=temp;
}
}
if(n==x) //素数
ans=x+1;
else if(n!=1 || cnt==1) //n为单因子或者没除完。
ans+=n;
printf("Case %lld: %lld\n",kase++,ans);
}
return 0;
}