一、题目分析
1.问题:设某未知正整数x满足:
(1)x和a0的最大公约数是a1;
(2)x和b0的最小公倍数是b1。
Hankson的“逆问题”就是求出满足条件的正整数x。
2.分析过程
(1)根据两个要求,得出判断x的条件;
(2)因为x是b1的约数,所以x <= b1,y = b1/x;y也可能符合条件,可以减少循环的次数,确定符合条件数的范围;
(3)每次输入4个数,将这4个数存放到数组中,输入n组数据,即处理n次;
二、程序分析
1.程序组成
1.1 两个类:
(1)Solve类:求出满足要求的x,并输出x的值和x的个数
(2)Improve类:测试类
1.2 三个方法
1.2.1 int Max(int a,int b){}
功能:求两个数的最大公约数
//求两个数的最大公约数(辗转相除法)
public static int Max(int a,int b){
if(a%b == 0){
return b;
}else{
return Max(b,a%b);
}
}
1.2.2 void improve(){}
功能:判断符合条件数的个数,并输出
/**
*
* @param: []
* @return: void
* @Description:判断符合条件数的个数,并输出
*/
public static void improve(){
int[] arrays = new int[4];
int count = 0;
for(int i = 0;i < 4;i++){
System.out.print("请输入第"+(i+1)+"个数:");
int number = new Scanner(System.in).nextInt();
//将输入的数字存到数组中
arrays[i] = number;
}
//x->(1-sqrt(array[3]))
for(int x = 1;x*x <= arrays[3];x++){
if(arrays[3]%x == 0){
//判断条件:x、arrays[0]的最大公约数是arrays[1];
// x和arrays[2]的最小公倍数是arrays[3];
if(Max(arrays[0],x) == arrays[1]&&((arrays[2]*x)/Max(arrays[2],x)) == arrays[3]){
count++;
System.out.print(x+" ");
}
int y = arrays[3]/x;
if(x == y){
continue;
}
if(Max(arrays[0],y) == arrays[1]&&((arrays[2]*y)/Max(arrays[2],y)) == arrays[3]){
count++;
System.out.print(y+" ");
}
}
}
System.out.println("满足条件的x有:"+count+"个");
}
1.2.3 void main(String[] args){}
功能:主方法,测试improve()方法,并输出结果
public static void main(String[] args) {
int k = 1;
while(k == 1){
System.out.println("请输入数据组数:");
int group = new Scanner(System.in).nextInt();
//循环输入组数次
for (int i = 0; i < group; i++) {
System.out.println("第" + (i + 1) + "组:");
new Solve().improve();
}
System.out.println("继续选择1,退出选择0");
k = new Scanner(System.in).nextInt();
}
}
1.3源程序代码:
package www.program.code;
import java.util.Scanner;
class Solve{
//求两个数的最大公约数
public static int Max(int a,int b){
if(a%b == 0){
return b;
}else{
return Max(b,a%b);
}
}
/**
*
* @param: []
* @return: void
* @Description:判断符合条件数的个数,并输出
*/
public static void improve(){
int[] arrays = new int[4];
int count = 0;
for(int i = 0;i < 4;i++){
System.out.print("请输入第"+(i+1)+"个数:");
int number = new Scanner(System.in).nextInt();
//将输入的数字存到数组中
arrays[i] = number;
}
//x->(1-sqrt(array[3]))
for(int x = 1;x*x <= arrays[3];x++){
if(arrays[3]%x == 0){
//判断条件:x、arrays[0]的最大公约数是arrays[1];
// x和arrays[2]的最小公倍数是arrays[3];
if(Max(arrays[0],x) == arrays[1]&&((arrays[2]*x)/Max(arrays[2],x)) == arrays[3]){
count++;
System.out.print(x+" ");
}
int y = arrays[3]/x;
if(x == y){
continue;
}
if(Max(arrays[0],y) == arrays[1]&&((arrays[2]*y)/Max(arrays[2],y)) == arrays[3]){
count++;
System.out.print(y+" ");
}
}
}
System.out.println("满足条件的x有:"+count+"个");
}
}
/**
* @Author:Star
* @Date:Created in 13:45 2019/3/21
* @Description:解决Hankson问题:
* 设某未知正整数x满足:
* 1、 x和a0的最大公约数是a1;
* 2、 x和b0的最小公倍数是b1。
* Hankson的“逆问题”就是求出满足条件的正整数x
*/
public class Improve {
public static void main(String[] args) {
int k = 1;
while(k == 1){
System.out.println("请输入数据组数:");
int group = new Scanner(System.in).nextInt();
//循环输入组数次
for (int i = 0; i < group; i++) {
System.out.println("第" + (i + 1) + "组:");
new Solve().improve();
}
System.out.println("继续选择1,退出选择0");
k = new Scanner(System.in).nextInt();
}
}
}
2.流程图分析
三、调试
1.输入0有错误产生
2.对输入数据0进行了处理
四、测试
1.输入数据非法
五、运行结果
六、总结
1.逆向思维的提高题,也可以通过将所求值放到已知方法中去,满足条件,则计数器+1;最后输出计数器的值即可。
2.对于一个问题的逆向化求解过程,以前也没有接触过,所以对于我来说编写出良好的代码有些难度,这次的程序采取了较为简单的代入法求解了问题,也是很好的一次训练机会,但是代码编写的还是很不好,后续会继续思考,希望大家可以找出一些做的不好的地方,互相共勉。