一、题目名称
一、题目名称:求N个数最大公约数,最小公倍数
二、题目内容:
求N个数最大公约数,最小公倍数。以及Hankson的逆问题。
已知a0,a1,b0,b1,设有一个x满足,x和a0的最大公约数是a1,
x和b0的最小公倍数是b1,求出这个x有几个。
样例格式; 2组
41 1 96 288 6
95 1 37 1776 2
三、算法设计:
(1)先用辗转相除法求出两个数的最大公约数,然后将最大公约数与下一个数进行计算求出新的最大公约数。最大公倍数也是一样的方法,先求出两个数的最大公倍数然后与下一个进行计算得出最后结果
(2)先输入有几组,一组4个数必须满足题目要求,可以调用山歌算法中计算最大公约数,最小公倍数的函数。满足要求后计算这样的结果x有几个
四、调试截图
图 2 调试最大公约数,最小公倍数计算
图 3 调试Hankson逆问题的数据合法性
五、测试结果:
图4 N个数最大公约数,最小公倍数
图5 Hankson的逆问题,满足条件的数
六、总结
我们最开始接触的是两个数求最大公约数和最小公倍数,现在要求是N个数,我第一时间想到的是可以将它设计为一个函数,求n个数的时候就可以调用这个函数前两个数的最大公约数在和下一个数继续求,做一个循环就可以了。遇到的困难就是提高部分开始没有思路,因为题目很长就不想看,到最后他举出例子的时候发现很容易理解,而且还可以调用第一个问题的函数,这时我就想到了switch case 语句做成两个部分可以进行选择,还有循环部分出了问题,查阅了类似的资料,在里面的函数学会到了以前不了解的语句。
源码
#include<stdio.h>
//辗转相除法
int max1(int a,int b)
{
int temp;
if(a<b) //若存在a小于b的情况,则交换数值
{
temp=a;
a=b;
b=temp;
}
while(b!=0) //直到b为0,通过赋值得到最大公约数为a的值
{
temp=a%b; //temp为余数
a=b; //将b的值赋给a
b=temp; //将余数temp的值赋给b
}
return a;
}
//求n个数的最大公约数
int max2(int a[],int n)
{
int x=a[0],y=a[1],z=0;
z=max1(x,y); //先计算出两个数的最大公约数,再用该最大公约数和下一个数求最大公约数,以此类推
for(int i=2;i<n;i++)
z=max1(z,a[i]);
return z;
}
//求两个数的最小公倍数
int min1(int a,int b)
{
int max1(int a,int b); //自定义函数返回值类型
int temp;
temp=max1(a,b); //再次调用自定义函数,求出最大公约数
return (a*b/temp); //返回最小公倍数到主调函数处进行输出
}
//求n个数的最小公倍数
int min2(int a[],int n)
{
int x=a[0],y=a[1],z=0;
z=min1(x,y);
for(int i=2;i<n;i++)
z=min1(z,a[i]);
return z;
}
void main()
{
int n=0,x=0,max=0,min=0,b,sum=0,i=0;
int c[4];
int a[]={
0};
printf(" 1.输入n个你想计算的正整数并计算\n");
printf(" 2.计算出Hankson的“逆问题”的答案\n");
printf("请选择你想要进行的操作:\n");
scanf("%d",&x);
while(x<1||x>2)
{
printf("没有这个选项,请重新输入:\n");
scanf("%d",&x);
}
switch(x)
{
case 1:
printf("请输入你想要计算的整数个数(大于1)");
scanf("%d",&n); //输入要计算最大公约数和最小公倍数的整数个数
printf("请依次输入整数:\n");
for(i=0;i<n;i++)
scanf("%d",&a[i]); //循环输入整数
max=max2(a,n); //调用函数,求出这些整数的最大公约数
min=min2(a,n); //调用函数,求出这些整数的最小公倍数
printf("这些数的最大公约数为:%d\n",max);
printf("这些数的最小公倍数为:%d\n",min);
break;
case 2:
printf("请输入数据的组数:");
scanf("%d",&b); //输入组数
printf("每组输入四个数,要求第一个数能被第二个数整除,第三个数能被第四个数整除\n");
for(;b>0;b--) //循环依次输入b个组
{
for(i=0;i<4;i++) //每组4个数
{
scanf("%d",&c[i]);
}
if(c[0]%c[1]!=0||c[3]%c[2]!=0) //判断输入的4个数是否满足第一个数能被第二个数整除,第三个数能被第四个数整除的条件
{
printf("输入不符合条件,请重新输入:\n");
for(i=0;i<4;i++)
{
scanf("%d",&c[i]);
}
}
for(int y=0;y<=c[3];y++) //循环计算有多少个满足条件的数
{
if(max1(y,c[0])==c[1]&&min1(y,c[2])==c[3]) //调用计算两个数的最大公约数和最小公倍数的函数,判断y是否满足条件
sum++;
}
printf("一共有%d个数满足条件\n",sum);
sum=0; //累加sum初始化
}
}
}
`