自我总结 (七)

Lowest Common Multiple Plus(这是数论算法中的基础算法程序)

Problem Description
求n个数的最小公倍数。

Input
输入包含多个测试实例,每个测试实例的开始是一个正整数n,然后是n个正整数。

Output
为每组测试数据输出它们的最小公倍数,每个测试实例的输出占一行。你可以假设最后的输出是一个32位的整数。

Sample Input
2 4 6
3 2 5 7

Sample Output
12
70

问题链接:HDU2028 Lowest Common Multiple Plus

问题简述:(略)

问题分析:最大公约数和最小公倍数是数论中的两个重要概念。以及求多个数的最大公约数和最小公倍数。

程序说明:

计算最小公倍数时,使用带参数的宏定义,而不是使用函数。这样做程序会略微快一些,因为省去了函数的调用、返回和参数传递。

参考链接:多个数求最小公倍数

代码如下:
第一次的代码:

#include <stdio.h>
#include <stdlib.h>
int Gcd(int m,int n);
int main()
{
	int n,i;
	while (scanf("%d",&n) != EOF)
	{
		if (n == 1)
		{
			int a;
			scanf("%d",&a);
			printf("%d\n",a);
		}
		else
		{
			int gcd;
			int sum;
			int *a = (int *)malloc(sizeof(int) * n);
			for (i = 0;i < n;i ++)
				scanf("%d",&a[i]);
			gcd = Gcd(a[0],a[1]);//具体看参考链接
			sum = a[0] / gcd * a[1];
			for (i = 2;i < n;i ++)
			{
				gcd = Gcd(sum,a[i]);
				sum = sum / gcd * a[i];
			}
			printf("%d\n",sum);
			free(a);
		}
	}
	return 0;
}
int Gcd(int m,int n)
{
	if (m % n == 0)
		return n;
	else
		return Gcd(n,m % n);
}


改进后的:

#include <stdio.h>
#define lcm(a, b) a / gcd(a, b) * b//带参数的宏定义,a*b会超int64,会出现RE。
long gcd(long m, long n)
{
    while(n)
    {
        long temp = m % n;
        m = n;
        n = temp;
    }
    return m;
}
 
int main(void)
{
    int n, lcmval, val;
 
    while(scanf("%d", &n) != EOF)
     {
        // 先读入一个数
        scanf("%d", &lcmval);
 
        // 读入n-1个数,同时计算最小公倍数
        while(n --) {
            scanf("%d", &val);
            lcmval = lcm(lcmval, val);
        }
        printf("%d\n", lcmval);
    }
 
    return 0;
}

递归求最大公约数:

long gcd(long m,long n)//利用了辗转相除法,所以不用考略m < n的情况。
{
	if (m % n == 0)
		return n;
	else 
		return gcd(n,m  % n);
}

总结:

1.c语言要输入输出一个32位的数字

(1)看看你的sizeof(int)等于多少了,如果结果为4,那么就是int就足够拉,打印时为%d;
如果是sizeof(long) == 4,那么就使用long,打印%ld。
(2)如果是相当大的数字,那么需要自行编码实现特殊的数据类型了,可以用字符串/链表之类的模仿,打印输出也是特殊定制的。

2.多个数的最大公约数算法

(1)自然而然会想到用逐轮用2个数计算,将上一步的最大公约数与下一个数继续计算,直到计算完所有数。
(2)上面的算法比较麻烦,因为不断调用内部有多次循环的 gcd 算法。其实,根据辗转相除法,我们可以这样做:
1.对这一组数进行排序(从大到小)
2.对每两个相邻的两个数进行如下操作:设相邻的两个数为A和B(A在前,因为已经排序,所以A > B),如果A = n * B(n为整数),也就是A能够被B整除,那么就令A = B;如果A不能被B整除则令A = A % B。
3.重复上面两步,直到数组中每个数都相等,则最大公约数就为这个数。

3.带参数的宏定义

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值