C++解决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的个数;

二、 算法构造

x是a1的倍数,b1的约数,可以枚举b1所有的约数来判断是否满足条件。 也可以使用数论的方法,将a0, a1, b0, b1分解因数,可以找到x对于每个质因子的范围,根据这个可以得到答案的公式(将每个质因子的范围相乘)。

三、 算法实现

#include <iostream>
using namespace std;

int gcd(int a,int b)//求最大公约数 
{
	 while(a!=b)
	 {
        if(a>b)
        a = a - b;
        if(a<b)
        b = b - a;
    }
	return a;
}

int lcm(int a,int b)//求最小公倍数 
{
	return a*b/gcd(a,b);
}

int main()
{
	int m,n,a0,a1,b0,b1,x;
	cin>>n;
	int times[n-1];//定义一个数组存储每四个数据的结果 
	for(m=n;m>0;m--)
	{
		cin>>a0>>a1>>b0>>b1;
		for(x=a1;x<=b1;x++)
		{
			if(gcd(x,a0)==a1&&lcm(x,b0)==b1)//跳出条件:x和a0的最大公约数为a1,x和b0的最小公倍数为b1 
			{
				times[n-m]+=1;
			}
		}
	}
	for(int j=n;j>0;j--)//将所得结果的数组输出 
	{
		cout<<times[n-j]<<endl; 
	}
	return 0;
}

四、测试、调试及运行过程

1)测试调试
在这里插入图片描述
这个错误主要是没有认清楚数组的跳出条件,下意识的-1使得循环出现错误无法跳出,一直卡在第二组数据的输入
在这里插入图片描述
这个错误是后期还原的,注释掉的部分是我当时没有写的部分,由于没做x的数值变化使得输入第二个值时没有跳出,出现错误。
还有一个错误是在输出的时候没有运用数组,输出的不是n个值而是一个值
2)运行
在这里插入图片描述

五、经验总结

1、进一步复习了最大公约数与最小公倍数的计算的算法,并对其递归调用有了更深的理解
2、在循环结构中一定要注意循环的跳出条件以及当需要输出多个相同地位的值时要为不同输入产生的输出定义不同的变量
3、经过相关资料的查询,这是一道算法题,而且对运行时间与所需内存都有其各自的要求,通过这次作业的完成,我认识到了优秀的算法设计与精简的代码所带来的高效率,希望我在今后的作业中也能实现高效率的算法

猜你喜欢

转载自blog.csdn.net/qq_42302466/article/details/88728370