求N个数的最大公约数和最小公倍数。用C或C++或java或python语言实现程序解决问题。并解决Hankson问题。

具体题目就不再过多描述。有兴趣的可以搜一下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();
	}
}

结果展示:在这里插入图片描述
总结:对代码的理解和解释我都写在了注释中,就不再详细解释了。做这道题我可能收获最大的就是对于数组的理解更深了。在方法中改变数组的值,主函数数组值也会改变哦。没改变的是数组地址值,这也是我为什么要在主函数中申请两个数组的原则。希望可以帮到大家!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值