具体题目就不再过多描述。有兴趣的可以搜一下hankson问题讲的是什么呢。
思路一之求最大公约数与最小公倍数:当只有两个数时,我们的问题将会变得简单。可以利用辗转相除法求得最大公约数。并利用两数之积除以最大公约数得最小公倍数。当变为n个数时,我才用了一种相对好理解的方法,就是分别两两计算,举例当有五个数时,我们求得1和2的最大公约数,并利用此公约数与三继续求得公约数,直到求五。最后的公约数便是这五个数的最大公约数。最小公倍数也是如此。
思路之二解决hankson问题:当时我在网上看了好多解决这个问题的办法,但都不明白。最后看了这位作者的算法解释才恍然大悟,为了防止我表达不清楚,大家可以直接去看下原文解释。
这是网址https://www.luogu.com.cn/problemnew/solution/P1072
代码部分:
import java.util.Scanner;
public class Homework {
public int gcd(int a,int b) {//求两个数的最大公约数
int temp;
if(b>a)
{
temp=a;
a=b;
b=temp;
}
while(b!=0)
{
temp=a%b;
a=b;
b=temp;
}
return a;
}
public int lcm(int a,int b) {//求两个数的最小公倍数
return a*b/gcd(a,b);//这是一个公式,即最小公倍数*最大公约数=两原数相乘
}
public int ngcd(int []m,int n) {//n个数的最大公约数
int max = 0;
for(int i=0;i<n-1;i++){//可以理解为依次两两求公约数,得到后在与下一个数求
max=gcd(m[i],m[i+1]);
m[i+1]=max;//这个挺重要的,举例当i=0时,数组0和1求得公约数,接下来应该是
} //此公约数与数组2求最大公约数。当下一轮时i=1,进行比较的是数组1和2.
//因此在i=0时,求得数组1,2公约数后,将此公约数max赋予m[i+1]
System.out.println("这些数中最大公约数为"+max);
return max;
}
public int nlcm(int []m,int n) {//n个数的最小公倍数
int min=0;
for(int i=0;i<n-1;i++) {
min=lcm(m[i],m[i+1]);
m[i+1]=min;
}
System.out.println("这些数中最小公倍数为:"+min);
return min;
}
public void hankson()//解决hankson问题
{
try (Scanner w = new Scanner(System.in)) {
int t;
System.out.println("请输入要计算的数据组数t:");
t=w.nextInt();
int []s=new int[t];
System.out.println("请输入要输入的数据");
for(int i=0;i<t;i++) {
int a=i+1;//定义行数
System.out.print("第"+a+"行:");
int a0,a1,b0,b1;
a0=w.nextInt();
a1=w.nextInt();
b0=w.nextInt();
b1=w.nextInt();
int p=a0/a1,q=b1/b0,ans=0;
for(int x=1;x*x<=b1;x++)
if(b1%x==0){
if(x%a1==0&&gcd(x/a1,p)==1&&gcd(q,b1/x)==1) ans++;
int y=b1/x;//得到另一个因子
if(x==y) continue;
if(y%a1==0&&gcd(y/a1,p)==1&&gcd(q,b1/y)==1) ans++;
}
s[i]=ans;
}
for(int i=0;i<t;i++) {
int a=i+1;
System.out.println("第"+a+"行结果为:"+s[i]);
}
}
}
public static void main(String[] args) {
System.out.println("请输入需要计算数据的个数n!");
Scanner y = new Scanner(System.in);
int n=y.nextInt();//
int []s=new int[n];//开辟数组空间
int []x=new int[n];
System.out.println("请分别输入计算的数据:");
for(int i=0;i<n;i++) {//分别赋予数组初值
s[i]=y.nextInt();
x[i]=s[i];//建立另一个相等数组,此举的目的是帮助实现nclm方法
} //因为在调用ngcd方法后,数组内的值也发生了改变。但地址没变。
Homework h=new Homework();//开辟空间
h.ngcd(s,n);//调用
h.nlcm(x,n);
System.out.println("------------------");
h.hankson();
}
}
结果展示:
总结:对代码的理解和解释我都写在了注释中,就不再详细解释了。做这道题我可能收获最大的就是对于数组的理解更深了。在方法中改变数组的值,主函数数组值也会改变哦。没改变的是数组地址值,这也是我为什么要在主函数中申请两个数组的原则。希望可以帮到大家!