编程作业二
基本要求:
求N个数的最大公约数和最小公倍数。用C或C++或java或python语言实现程序解决问题。
1.程序风格良好(使用自定义注释模板)
2.提供友好的输入输出,并进行输入数据的正确性验证。
提高要求:已知正整数a0,a1,b0,b1,设某未知正整数x满足:
1.x和a0的最大公约数是a1;
2.x和b0的最小公倍数是b1。
求解满足条件的x的个数。
输入格式
输入第一行为一个正整数n,表示有n组输入数据。接下来的n行每行一组输入数据,为四个正整数a0,a1,b0,b1,每两个整数之间用一个空格隔开。输入数据保证a0能被a1整除,b1能被b0整除。
输出格式
输出共n行。每组输入数据的输出结果占一行,为一个整数。
对于每组数据:若不存在这样的x,请输出0;
若存在这样的x,请输出满足条件的x的个数;
总结
这次的程序用到了上次上机的代码,并在它的基础上拓展延伸,从求两个数的最大公约数和最小公倍数到求指定的任意数的最大公约数和最小公倍数,这其中核心的思想没有变。
求N个数其实也是求两个数的,但是还要把这个结果与下一个数再求公约数和公倍数,以此类推,得到n个数的共同最大公约数和最小公倍数。
提高要求中是以上的逆运算,求一个数x,x满足x和a0的最大公约数是a1,x和b0的最小公倍数是b1。这就是x要符合的条件。我设定了一个足够大的范围,在这个范围里去找x,当x满足这两个条件时,计数器count++,直至最后输出count就为x的个数。
看到题目,先要在脑中构思算法,仔细思考自己应如何实现,有一个成熟的构思后,再看能否用编程语言实现自己的算法。
**源代码
#include<stdio.h>
#include<iostream.h>
#include<math.h>
#define MAX 100
int divisor (int a,int b) /*自定义函数求两数的最大公约数*/
{
int temp; /*定义整型变量*/
if(a<b) /*通过比较求出两个数中的最大值和最小值*/
{ temp=a;a=b;b=temp;} /*设置中间变量进行两数交换*/
while(b!=0) /*通过循环求两数的余数,直到余数为0*/
{
temp=a%b;
a=b; /*变量数值交换*/
b=temp;
}
return (a); /*返回最大公约数到调用函数处*/
}
int multiple (int a,int b) /*自定义函数求两数的最小公倍数*/
{
int divisor (int a,int b); /*自定义函数返回值类型*/
int temp;
temp=divisor(a,b); /*再次调用自定义函数,求出最大公约数*/
return (a*b/temp); /*返回最小公倍数到主调函数处进行输出*/
}
void Ndivisormultiple() //求N个数的最大公约数和最小公倍数
{ int a1[MAX];
int count,j,b,i,c=1,d;
printf("您要比较几个数?\n");
scanf("%d",&count);
printf("请输入数据\n");
for(i=0;i<count;i++)
{
scanf("%d",&a1[i]);
}
for(j=0;j<=count-2;j++)//求最大公因数
{
d=divisor(a1[j],a1[j+1]);
b=divisor(d,a1[j+2]);
}
printf("您所输入的%d个数字的最大公约数为%d\n",count,b);
for(i=0;i<count-2;i++)//求最小公倍数
{
c=multiple(a1[i],a1[i+1]);
d=multiple(c,a1[i+2]);
}
printf("您所输入的%d个数字的最小公倍数为%d\n\n",count,d);
}
void antidivisormultiple( ) //最大公因数和最小公倍数的逆运算
{
int count=0,a,b,i,j;
int b1[MAX][4];
printf("您想要输入几组值\n");
scanf("%d",&b);
printf("请输入数据\n");
for(i=0;i<b;i++)
for(j=0;j<4;j++)
{ scanf("%d",&b1[i][j]);}
for(i=0;i<b;i++)//判断数据是否满足整除条件
{
if((b1[i][0]%b1[i][1])!=0)
{
cout<<"输入的值不满足整除条件,请重新输入第"<<i+1<<"组的a0,a1"<<endl;
scanf("%d %d",&b1[i][0],&b1[i][1]);
}
if((b1[i][3]%b1[i][2])!=0)
{
cout<<"输入的值不满足整除条件,请重新输入第"<<i+1<<"组的b0,b1"<<endl;
scanf("%d %d",&b1[i][2],&b1[i][3]);
}
}
for(j=0;j<b;j++)
{ i=0;count=0;
while(i<20000)//在一个较大的范围里面找x
{
if(i%b1[j][0]!=0)
{ if(divisor(i,b1[j][0])==b1[j][1])//判断x和a0的最大公因数是否为a1
{
a=multiple(i,b1[j][2]);//判断x和b0的最小公倍数是否为b1
if(a==b1[j][3])
count++;
}
}
i++;
}
printf("第%d组满足条件的x有%d个",j+1,count);
printf("\n");
}
}
//主函数
int main()
{
char select='Y';
while(select=='Y')
{
printf("请选择\n");
cout<<"1.求N个数的最大公约数和最小公倍数"<<endl;
cout<<"2.最大公约数和最小公倍数的逆运算"<<endl;
int num;
cin>>num;
switch (num)
{
case 1: Ndivisormultiple( );break;
case 2: antidivisormultiple( );break;
}
cout<<"是否继续操作?(Y/N)"<<endl;
cin>>select;
}
return 0;
}
1.算法设计思路
1.1求N个数的最大公约数和最小公倍数
1.2最大公约数和最小公倍数的逆运算
1.3主函数
2. 调试及测试
2.1调试截屏
(1)最大公约数和最小公倍数调试截屏
(2)最大公约数调试截屏
(3)最大公约数和最小公倍数的逆运算截屏
(4)主函数调试截图
(5)以上调试的运行截图
2.2测试截屏
(1)最大公约数和最小公倍数函数的测试截图
(2)最大公约数和最小公倍数函数的逆运算的测试截图
(3)对数据格式输入非法的测试截图
(4)对支持用户继续操作或退出的功能测试
(5)完整测试