[HODJ]1019. Least Common Multiple

题目本意是求一系列数的最小公倍数,我在博客中的一篇文章中已经写过一篇总结的文章,这里就不再赘述。
本题需要注意的就是,在题目输入的要求中有一句话:All integers will be positive and lie within the range of a 32-bit integer.
所以在求最小公倍数的函数中,要做些小手脚。经测试,如果按照以下方式写:
int lcm(int a,int b)
{
    return a*b/gcd_recursive(a,b);
}
得到的是Wrong Answer.原因是a*b可能会超出32位的int所能表示的范围。所以要修改成如下代码:
int lcm(int a,int b)
{
    return a*(b/gcd_recursive(a,b));
}
多加一个括号后就能避免这个问题了.
AC代码如下:

// 算法描述
// 前提:a > b > 0
// 返回:a和b的最大公约数
#include  < iostream >
using   namespace  std;
int  gcd_recursive( int  a, int  b)
ExpandedBlockStart.gifContractedBlock.gif
{
    
int temp;
    
if(a < b)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
{
        temp 
= a;
        a 
= b;
        b 
= temp;
    }

    
if(b == 0)
        
return a;
    
else
        
return gcd_recursive(b,a%b);
}

int  gcd_non_recursive( int  a, int  b)
ExpandedBlockStart.gifContractedBlock.gif
{
    
int r;
    r 
= a%b;
    
while(r != 0)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
{
        a 
= b;
        b 
= r;
        r 
= a%b;
    }

    
return b;
}

// 如果是求一系列数的最大公约数,那么就可以采用递归方式从最后一个数开始
// 逐个计算一个数组的最后一个数a[n-1]和前n-1个数的最大公约数就可以了
// 以下的求一系列数的最小公倍数道理相同
int  gcd_n( int   * a, int  n)
ExpandedBlockStart.gifContractedBlock.gif
{
    
if(n == 1)
        
return *a;
    
else
        
return gcd_recursive(a[n-1],gcd_n(a,n-1));
}

// 求两个数的最小公倍数
// 方法:两个数的乘积除以两个数的最大公约数
// 即:lcm = a*b/gcd(a,b)
int  lcm( int  a, int  b)
ExpandedBlockStart.gifContractedBlock.gif
{
    
return a*(b/gcd_recursive(a,b));
}

int  lcm_n( int   * a, int  n)
ExpandedBlockStart.gifContractedBlock.gif
{
    
if(n == 1)
        
return *a;
    
else
        
return lcm(a[n-1],lcm_n(a,n-1));
}

int  main()
ExpandedBlockStart.gifContractedBlock.gif
{
    
int N;
    cin
>>N;
    
while(N--)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
{
        
int n;
        
int *p; 
        cin
>>n;
        p 
= new int[n];
        
for(int i = 0;i < n;++i)
            cin
>>p[i];
        cout
<<lcm_n(p,n)<<endl;
        delete []p;
    }

    
return 0;
}

 

转载于:https://www.cnblogs.com/krisdy/archive/2009/04/20/1439886.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值