UVA 10791 Minimum Sum LCM

Question:
LCM (Least Common Multiple) of a set of integers is defined as the minimum number, which is a
multiple of all integers of that set. It is interesting to note that any positive integer can be expressed
as the LCM of a set of positive integers. For example 12 can be expressed as the LCM of 1, 12 or
12, 12 or 3, 4 or 4, 6 or 1, 2, 3, 4 etc.
In this problem, you will be given a positive integer
N. You have to find out a set of at least two positive integers
whose LCM is N. As infinite such sequences are
possible, you have to pick the sequence whose summation
of elements is minimum. We will be quite happy
if you just print the summation of the elements of this
set. So, for N = 12, you should print 4+3 = 7 as
LCM of 4 and 3 is 12 and 7 is the minimum possible
summation.
Input
The input file contains at most 100 test cases. Each
test case consists of a positive integer N (1 ≤ N ≤
2
31 − 1).
Input is terminated by a case where N = 0. This
case should not be processed. There can be at most
100 test cases.
Output
Output of each test case should consist of a line starting with ‘Case #: ’ where # is the test case
number. It should be followed by the summation as specified in the problem statement. Look at the
output for sample input for details.
Sample Input
12
10
5
0
Sample Output
Case 1: 7
Case 2: 7
Case 3: 6
题意大意:给你一个数n,让你找到至少两个数使其LCM()为n,输出其最小和。
思路:找到多个数使其的LCM为n并使和最小,首先这个数肯定不能存在非1的公因数,所以我们将n质因数分解,并把相同的部分相乘,使这几个数不存在非1公因数。算出的和此时为最小
(http://acm.hust.edu.cn/vjudge/contest/121559#problem/J)

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long LL;
LL temp,res;
int prime[100010],vis[100010],curn=0;
void init()
{
    memset(vis,0,sizeof(vis));  //打印素数表
    for(int i=2;i<=100005;i++)
    {
        if(!vis[i])
        {
            prime[curn++]=i;
            for(int j=2;j*i<=100005;j++)
                vis[i*j]=1;
        }
    }
}
int main()
{
    init();
    int T=1;
    while (1)
    {
        int n,h=0;
        res=0;temp=1;
        scanf("%d",&n);
        if(n==0)
            break;
        for(int i=0;i<curn;i++)
        {
            temp=1;
            if(n==1)
                break;
            else
            {
                if(n%prime[i]==0)
                {
                    while(n%prime[i]==0)
                   {
                       temp*=prime[i];  // 将质因数相同的部分相乘。
                       n/=prime[i];
                   }
                   res+=temp;
                   h++;
                }
            }
        }
        if(n!=1||h==0)  //可能输入的数为质数,不存在真因子。并判断输入的n是否为1
        {
            res+=n;
            h++; 
        }
        if(h==1)    //如果h==1,则说明n为一或者为素数 
            res++;
        printf("Case %d: %lld\n",T++,res);
    }
    return 0;
}

体会:开始并没有想到这点,后来经人指点才明白了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值