一、题目
-
基本要求:
求N个数的最大公约数和最小公倍数。用C或C++或java或python语言实现程序解决问题。
-
提高要求:
Hanks博士是BT(Bio-Tech,生物技术)领域的知名专家,他的儿子名叫Hankson。现在,刚刚放学回家的Hankson正在思考一个有趣的问题。
今天在课堂上,老师讲解了如何求两个正整数c1和c2的最大公约数和最小公倍数。现在Hankson认为自己已经熟练地掌握了这些知识,他开始思考一个“求公约数”和“求公倍数”之类问题的“逆问题”,这个问题是这样的:已知正整数a0,a1,b0,b1,设某未知正整数x满足:
1、x和a0的最大公约数是a1;
2、x和b0的最小公倍数是b1。
Hankson的“逆问题”就是求出满足条件的正整数x。但稍加思索之后,他发现这样的x并不唯一,甚至可能不存在。因此他转而开始考虑如何求解满足条件的x的个数。请你帮助他编程求解这个问题。
二、算法设计思路
- 基础要求:
① 写出求取最大公约数的函数
② 将要求最大公约数与最小公倍数的数据存入数组
③ 递归调用函数,两两进行比较
- 提高要求:
① 写出求取最大公约数的函数
② 采用枚举的方法
③ 求出满足条件的x的个数sum
三、流程图
-
基础要求:
-
提高要求:
四、代码测试
- 对求最大公约数与最小公倍数代码的测试
- 提高要求中,数据输入错误时
- 当数x与a0最大公约数为a1时,满足条件的x的个数
- 当数x与b0最小公倍数为b1时,满足条件的x的个数
五、代码调试
调试后发现由于数组角标越界,无法正常输出
修改后:
六、运行截屏
- 基础要求:
- 提高要求:
输入错误时:
七、经验总结
通过这次作业,复习了递归函数的用法——递归就是一个函数在它的函数体内调用它自身。执行递归函数将反复调用其自身,每调用一次就进入新的一层。递归函数必须有结束条件。当函数在一直递推,直到遇到结束条件后返回,递归要有两个要素,结束条件与递推关系。同时,也更加关注数组角标越界问题,以后编程时会更加注意。
八、源代码
- 基础要求:
package hello;
import java.util.Scanner;
import java.util.Arrays;
public class Many {
public static int gcd(int a,int b) { //求最大公约数
int temp;
if(a<b) {
temp=a;a=b;b=temp;
}
while(b!=0) {
temp=a%b;
a=b;
b=temp;
}
return a;
}
public static int gbsh(int c,int d) { //求最小公倍数
return c*d/gcd(c,d);
}
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int n;
int q,p;
n=sc.nextInt();
int[] array=new int[n];
for(int i=0;i<array.length;i++) {
array[i]=sc.nextInt();
}
System.out.println(Arrays.toString(array));
p=q=array[0];
for(int i=0;i<array.length;i++) {
if(i+1==array.length) {
break;
}else {
p=gcd(p,array[i+1]);
q=gbsh(q,array[i+1]);
}
}
System.out.println("这"+n+"个数的最大公约数为:"+p);
System.out.println("这"+n+"个数的为:"+q);
}
}
- 提高要求:
package hello;
import java.util.Scanner;
public class X {
public static int gcd(int a,int b) { //求最大公约数
int temp;
if(a<b) {
temp=a;a=b;b=temp;
}
while(b!=0) {
temp=a%b;
a=b;
b=temp;
}
return a;
}
public static void main(String[] args) {
int a0,a1,b0,b1;
int t;
int n; //要输入几组数据
int num; //记录多少个数据
Scanner sc=new Scanner(System.in);
n=sc.nextInt();
while(n-->0) {
a0=sc.nextInt();
a1=sc.nextInt();
b0=sc.nextInt();
b1=sc.nextInt();
if(a1%a0!=0&&b0%b1!=0) {
System.out.println("输入数据保证a0能被a1整除,b1能被b0整除");
break;
}
t=0;
num=0;
for(int i=1;i<1000;i++) {
if(gcd(i,a0)==a1) {
t=i;
break;
}
}
for(int j=t;j<=b1;j++){
int p,q;
p=j;
q=b0;
if(p*q/gcd(j,b0)==b1)
num++;
}
System.out.println(num);
}
}
}