[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)
{
    
int temp;
    
if(a < b)
    
{
        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)
{
    
int r;
    r 
= a%b;
    
while(r != 0)
    
{
        a 
= b;
        b 
= r;
        r 
= a%b;
    }

    
return b;
}

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

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

int main()
{
    
int N;
    cin
>>N;
    
while(N--)
    
{
        
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;
}

 

posted on 2009-04-20 19:36  笔记  阅读(643)  评论(0编辑  收藏  举报

导航