N个数的最大公约数和最小公倍数以及HANkson问题

N个数的最大公约数和最小公倍数以及HANkson问题

1.题目分析
1.基本要求:求N个数的最大公约数和最小公倍数。用C或C++或java或python语言实现程序解决问题)。
2.提高要求:进行最大公约数和最小公倍数求解的逆运算。(已知某数和一个数a0的最大公约数为a1,和另外一个数b0的最小公倍数为b1,求满足条件的数x的数量,可以进行多组)
在进行本次题目程序编写前,应该考虑以下几点:
① 进行n个数的最大公约数求解时,要先设置一个数组用于存储输入的N个数。
② 设置N个数求最大公约数的算法思想。
③ 在进行完最大公约数的求解后,求出N个数的最小公倍数。
④ 进行最大公约数和最小公倍数求解的逆运算时,需要注意要使输入的几个数满足条件:前两个之间满足整除关系,后两个数同样满足整除关系。
⑤ 在某一个范围内找到满足条件(x和一个数a0的最大公约数为a1,和另外一个数b0的最小公倍数为b1,)的x,并输出其数量。
2.算法构造
1.数据输入与存储:求最大公约数的n个数存储在数组(a[MAX]中MAX的值由宏定义决定),n个数由随机函数产生。(a[i]=rand()%100+1;);进行最大公约数和最小公倍数逆运算的数由键盘输入(输入第一行为一个正整数n,表示有n组输入数据。接下来的n行每行一组输入数据,为四个正整数a0,a1,b0,b1,每两个整数之间用一个空格隔开。此处输进行异常处理,数据保证a[i][1]能被a[i][0]整除,a[i][3]能被a[i][2]整除),输入数存储在数组a[MAX][4].
2.具体算法构造:①求N个数的最大公约数和最小公倍数算法(调用函数count()):是运用for循环对数组a[MAX]相邻元素进行最大公约数求解,求最小公倍数调用函数(doub())。②求最大公因数采用的是辗转相除法。求最大公约数和最小公倍数的逆算法是:在某一个范围内找到满足条件(x和一个数a[i][0]的最大公约数为a[i][1],和另外一个数a[i][2]的最小公倍数为a[i][3])的x,并输出x的数目(调用函数Excountn())。
3.算法实现

#include <stdio.h>
#include <stdlib.h>
#define MAX 1024
int first(int a,int b)//辗转相除法(函数嵌套调用)
{int temp;//设置一个中间量将大的数放在a中,小的数放在b中。
if(a<b)
{temp=a;
a=b;
b=temp;}
while(b!=0)//通过循环求两数余数,知道余数为0
{temp=a%b;
a=b;//变量数值交换,把数值较大的b放到a中,余数放到b中
b=temp;}
return a;}
int doub(int a[],int n,int yue)//求最小公倍数
{int i;
int s=1;
for(i=0;i<n;i++)
s=s*a[i]/yue;
return s;
}
void CountN()//求任意数量个数的最大公约数和最小公倍数
{int a[MAX];
int i,x,n,yue,bei,j;
int cnt;
printf("请输入你要求最大公约数的数据个数:\n");
scanf("%d",&n);
printf("获取的%d个随机数为:\n",n);
for(i=0;i<n;i++)
a[i]=rand()%100+1;//运用Rand()产生1~100之间任意数量的随机数
for(i=0;i<n;i++)
printf("%d\t",a[i]);
printf("\n");
x=a[0];     //数组相邻两个数进行最大公约数求解
for(i=1;i<n;i++)
{yue=first(x,a[i]); //调用最大公约数求解函数
}
bei=doub(a,n,yue);   //调用最小公倍数求解函数
printf("\n求得的最大公约数为:%d\n",yue);
printf("\n求得的最小公倍数为:%d\n",bei);
}
void Excountn() //最大公约数和最小公倍数的逆用
{int  a[MAX][4];//建立一个数组用于存放每次输入的数
int i,j,x,n,tag=1,cnt=0,q,p;
printf("请输入要进行x求解的组数\n");
scanf("%d",&n);
printf("请输入%d组满足以下条件的数\n1.第一个数可以被第二个数整除\n2.第四个数可以被第三个数整除\n",n);
while(tag)
{
	for(i=0;i<n;i++)
	{
		for(j=0;j<4;j++)
			scanf("%d",&a[i][j]);
		if((a[i][0]%a[i][1]!=0)||(a[i][3]%a[i][2]!=0))//判断输入的四个数是否满足关系a0%a1==0;b1%b0==0;
			printf("输入错误!将重新输入\n");//若不满足关系将重新输入四个数
		else tag=0;
	}
}
for(i=0;i<n;i++)
{cnt=0;
x=1;
while(x<20000)//在1~20000之间找满足和a0最大公约数为a1,和b0最小公倍数为a2的x有多少个
{
	q=first(a[i][2],x);
	p=first(a[i][0],x);
	int s=a[i][2]*x/q;
	x++;
	if(a[i][1]==p&&a[i][3]==s)
	{cnt++;}
}
printf("满足第%d组条件的有:%d个\n",i+1,cnt);
}
}
int main()
{int tag;
printf("请进行功能选择\n1.求多个数的最大公约数\n2.求最大公约数和最小公倍数之间的逆用\n ");
scanf("%d",&tag);
switch(tag)
{
case 1:CountN();break;
case 2:Excountn();break;
}
return 0;}

4.调试、测试及运行结果
调试结果:在这里插入图片描述

测试结果:
① 求N个数的最大公约数和最小公倍数函数Countn()的测试
在这里插入图片描述
② 求最大公约数和最小公倍数的逆运算的测试在这里插入图片描述

在这里插入图片描述
在这里插入图片描述运行结果:在这里插入图片描述
在这里插入图片描述
5.经验归纳
本次作业是求N个数的最大公约数和最小公倍数。并进行最大公约数和最小公倍数求解的逆运算。(已知某数和一个数a0的最大公约数为a1,和另外一个数b0的最小公倍数为b1,求满足条件的数x的数量,可以进行多组),在程序编写过程中,遇到的主要问题是对求多个数的最大公约数算法分析不清楚,以至于结果错误。通过这次作业我得到的感悟是:遇到困难时的心态要平和,冷静地去查找问题并解决问题。注意知识的总结和积累。最近,其实不止是本次程序实验带给我的收获,就是作为一个合格的程序员,要注意对知识的积累和知识体系的梳理,每隔一段时间就应该对自己近期的工作有个小结和反思,只有这样,才能不断进步,因此,我在CSDN开通了自己的博客,关于本次实验写的知识点总结在里面都有。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值