问题描述:
Hanks博士是BT(Bio-Tech,生物技术)领域的知名专家,他的儿子名叫Hankson。现在,刚刚放学回家的Hankson正在思考一个有趣的问题。
今天在课堂上,老师讲解了如何求两个正整数c1和c2的最大公约数和最小公倍数。现在Hankson认为自己已经熟练地掌握了这些知识,他开始思考一个“求公约数”和“求公倍数”之类问题的“逆问题”,这个问题是这样的:已知正整数a0,a1,b0,b1,设某未知正整数x满足:
1、 x和a0的最大公约数是a1;
2、 x和b0的最小公倍数是b1
题目分析:
模块:输入模块,处理模块,判断模块,输出模块。
输入格式:
输入第一行为一个正整数n,表示有n组输入数据。接下来的n行每行一组输入数据,为四个正整数a0,a1,b0,b1,每两个整数之间用一个空格隔开。输入数据保证a0能被a1整除,b1能被b0整除。
输出格式:
输出共n行。每组输入数据的输出结果占一行,为一个整数。
对于每组数据:若不存在这样的x,输出0;
若存在这样的x,请输出满足条件的x的个数;
算法实现:
public class Main {
/**
* 辗转相除法求最大公约数
* @param a
* @param b
* @return
*/
static int maxG(int a,int b){
int min,max,r;
//把a,b中最小的赋值给min
min= a>b? b:a;
//把a,b中最大的赋值给max
max=b>a? b:a;
while(min!=0){
r=max%min;
max=min;
min=r;
}
return max;
}
/**
* 求最小公倍数
* @param a
* @param b
* @param max a,b的最大公约数
* @return
*/
static int minG(int a,int b,int max){
int min;
return min=a*b/max;
}
public static void main(String[] args) {
System.out.println("输入组数:");
Scanner scanner=new Scanner(System.in);
//输入组数
int n=scanner.nextInt();
int[] a0=new int[n];
int[] a1=new int[n];
int[] b0=new int[n];
int[] b1=new int[n];
//输入每组数据
for(int i=0;i<n;i++)
{
System.out.println("输入第"+(i+1)+"组数据,并确保a0能被a1整除,b1能被b0整除");
a0[i]=scanner.nextInt();
a1[i]=scanner.nextInt();
b0[i]=scanner.nextInt();
b1[i]=scanner.nextInt();
if (a0[i]%a1[i]!=0||b1[i]%b0[i]!=0){
System.out.println("第"+(i+1)+"组数据输入错误");
break;
}}
int[] count=new int[n];
//通过循环求出符合要求的数
for(int i = 0; i<n;i++){
for(int j=a1[i];j<b1[i]+1;j++){
if(maxG(j,a0[i])==a1[i]&&minG(j,b0[i],maxG(j,b0[i]))==b1[i]){
count[i]++;
}
}System.out.println("符合第"+(i+1)+"组的个数为:"+count[i]);
}
}
}
测试
1、测试用例
n=1
a0=12,a1=4,b0=4,b1=16
输出结果:满足要求的数为1
2、测试用例
n=2
a0=15,a1=3,b0=6,b1=18
a0=15,a1=4,b0=7,b1=18
输出结果:满足第一组的数字有两个,第二组的数据输入错误。
总结
求最大公约数最小公倍数的方法有很多种,本文讲的是辗转相除法,如果你有更好的方法可以评论出来,互相交流学习。