提高~~~
作者:无*
时间:2019-3-21
一.题目分析:
1.基本要求:
求N个数的最大公约数和最小公倍数。
运用两个数求最大公约数和最小公倍数的方法,类比求出N个数的最大公约数和最小公倍数,此处可以分别别写四个函数进行相关调用。
2.提高要求:
已知正整数a0,a1,b0,b1,设某未知正整数x满足: x和b0的最小公倍数是b1。Hankson的“逆问题”就是求出满足条件的正整数x。
设置组数,编写循环,并判断是否满足条件对于每组数据:若不存在这样的x,请输出0;若存在这样的x,请输出满足条件的x的个数;
二.算法构造:
1.基本要求:
(1)先写出求两个数的最大公约数gcd( )和最小公倍数multiple( )的函数
(2)再分别写两个求N个数的相应函数,包含一个for循环for(i=2; i<n; i++) ,思想主要就是:前两个数求最大公约数,再依次与后面的数进行比较,求得最终结果。
2.提高要求:
(1)设置数组大小,for循环存入每组数据(每组四个数据)
(2)四个正整数分别a0,a1,b0,b1,输入数据保证a0能被a1整除,b1能被b0整除(a0%a1!=0||b1%b0!=0)。若不存在这样的x,请输出0;
(3)若存在这样的x,在while循环中继续执行判断gcd(a0,x)==a1&&multiple(b0,x)==b1。若满足定义一个标志(初值为0)进行自加。最后输出个数。
三.源代码:
#include"stdio.h"
#include"stdlib.h"
#include"time.h"
#define MAX 100
//两个数求最大公约数
int gcd(int n,int m)
{
int temp;
if(n<m)
{ temp=n;n=m;m=temp;}
while(m!=0) /*通过循环求两数的余数,直到余数为0*/
{
temp=n%m;
n=m;
m=temp;
}
return (n);
}
//求两个数最小公倍数
int multiple (int n,int m)
{
int gcd(int n,int m);
int temp;
temp=gcd(n,m);
return (n*m/temp);
}
//n个数求最大公约数
int max(int zu[],int n)
{
int a=zu[0],b=zu[1];
int c=gcd(a,b); //对前两个数求最大公约数
int i;
for(i=2; i<n; i++) //依次与数组后面元素比较求最大公约数
{
c=gcd(c,zu[i]);
}
return c;
}
//求n个数最小公倍数
int min(int zu[],int n)
{int a=zu[0],b=zu[1];
int c=multiple(a,b); //对前两个数求最小公倍数
int i;
for(i=2; i<n; i++) //依次对后面的数比较
{
c=multiple(c,zu[i]);
}
return c;
}
void hanshu(int n) //逆序的最大公约数与最小公倍数
{ int i,j,a0,a1,b0,b1;
int a[MAX]; //利用此数组记录每组的结果
int sum=0; // sum代表个数,初值为0
printf("依次输入数据:\n");
for(i=0;i<n;i++) //n代表组数
{ scanf("%d%d%d%d",&a0,&a1,&b0,&b1);
if(a0%a1!=0||b1%b0!=0)
{ printf("0\n"); continue;}
int x=1; sum=0;
while(x<40000) //此处为所查找数的自定义范围
{
if(gcd(a0,x)==a1&&multiple(b0,x)==b1) //x是a1的整数倍并且x是b1的因子
sum++;
x++;}
a[i]=sum;
}
for(i=0;i<n;i++)
{
printf("%d\n",a[i]); //输出所得结果
}
}
int main()
{
int num; int x;
int i,n;
int a[MAX];
printf("***请选择你要进行的操作***\n");
printf("1. **求N个数的最大公约数和最小公倍数**\n");
printf("2. **Hankson的“逆问题”**\n");
scanf("%d",&x);
switch(x)
{case 1:
{printf("请输入要比较数据的个数\n");
scanf("%d",&num);
printf("请依次输入元素\n");
for(i=0;i<num;i++) //遍历
{ scanf("%d",&a[i]);
}
printf("\n");
printf("最大公约数为%d\n",max(a,num)); //调用最大公约数函数
printf("最小公倍数为%d\n",min(a,num)); //调用最小公倍数函数
break;
}
case 2:
{ printf("请输入要比较的组数:\n");
scanf("%d",&n);
hanshu(n);
break;
}
}
return 0;
}
四.调试,测试及运行结果
1.调试:
2.测试:
(1)基本要求代码和运行结果:
(2)提高要求(逆序的求法)
3.运行结果:
此处加了switch( )语句进行功能选择,1代表求N个数的最大公约数和最小公倍数;2代表Hankson的逆问题。
五.经验归纳及心得
此次程序是对上次求两个数的最大公约数及最小公倍数的一个扩展,主要思想就是:先比较前两个数,得出结果后依次与后面的数进行比较,最后得出要求的结果。而提高要求则是对这一功能的逆序,提高要求编写要注意循环存入数据,并进行判断,再次运用了最大公约数及最小公倍数的调用实现功能,此处注意while( )语句的应用,及表示个数的标志要赋初值0;并在下一次循环时恢复0,否则,统计个数会出现错误。
*** * 心得: 此次程序是对上次程序的一个提高,在这次编程过程中,也遇到了一些错误,比如说:循环的正确应用,其次就是在函数调用时参数的传递问题,通过一步步的调试,测试也解决了相应的问题,对函数调用,数组,循环等知识进行了巩固。*