题目链接:
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1732
#include <cstdio>
#include <cmath>
// 对该数进行质因数分解的质数及其指数的和
long long sum;
long long x;
bool is_prime(long long n);
int main()
{
int count = 1;
while(scanf("%lld", &x) == 1 && x != 0)
{
sum = 0;
// 如果x为1
if(x == 1)
printf("Case %d: 2\n", count);
// 如果x为素数
else if(is_prime(x))
printf("Case %d: %lld\n", count, 1+x);
else
{
int p_count = 0;
// 求该数的质因数分解的每项和
long long k = x;
for(long long i = 2; i <= x; i++)
{
if(is_prime(i))
{
int e_count = 0;
while(k % i == 0)
{
e_count++;
k = k / i;
}
if(e_count > 0)
{
sum += pow(i, e_count);
p_count++;
}
if(k == 1)
break;
}
}
if(p_count >= 2)
printf("Case %d: %lld\n", count, sum);
else
printf("Case %d: %lld\n", count, sum+1);
}
count++;
}
return 0;
}
// 判断n是否为素数
bool is_prime(long long n)
{
if(n < 2)
return false;
for(long long i = 2; i*i <= n; i++)
{
if(n % i == 0)
return false;
}
return true;
}
一时不知如何做,看书发现是将N进行质因数分解,每个数单独作为一个元素,相加和最小。
根据最小公倍数的定义,每个数不能再分割。另外,如果把两个数或两个以上的数相乘,肯定比原来单独的数相加的和要大。
设两个数为a, b. a*b >= 2*max(a,b) > a+b. 因此是每个数单独作为一个元素和最小。
另外,这里需要求一个数N(可达2^31-1)的质因数分解,筛法是不能用了,因为要求1-2^31的素数。
一开始想得是从2开始,判断每个数是否为素数,如果是,就对其进行分解。
后来看了汝佳的代码,发现不用判断素数。
从2开始,如果该数能整除现在的N,就必定是素数,可质因数分解。
原因是,想一想以前学的分解质因数手算的方法。如果x是合数,但是能整除现在的N是不可能的。设x质因数分解中有质数a. 因为a比x小,a必定已经逐步整除过N.
现在的N必定不能被a整除。矛盾!因此,每一步能够整除现在的N的数必定为质数。