最大公约数和最小公倍数


一、题目

描述

输入两个正整数 x​0,y0,求出满足下列条件的P,Q的个数:1.P,Q 是正整数。2.要求P,Q以 x0为最大公约数,以 y 0为最小公倍数。

试求:满足条件的所有可能的 P,Q 的个数。

输入描述

一行两个正整数x0,y0(2≤x0,y0≤105 ) 。

输出描述

一行一个数,表示求出满足条件的 P,Q 的个数。
用例输入 1
10 20
用例输出 1
2
用例输入 2
3 60
用例输出 2
4

二、思路

(1).首先要知道怎么求最大公约数和最小公倍数,最大公约数就递归或者辗转相除

(1)递归:
int gcd(int a,int b)
{
	while(b>0)
	{
		if(a%b==0) return b;
		else return gcd(b,a%b);//这样写的可以提高代码效率,而且比较方便
	}
}
(2)辗转相除就不介绍了,可以去了解了解(这个属于迭代法)
       

要是想更简单,可以用c++的库函数__gcd(a,b),注意gcd前面是两个下划线,这个更快

(2).知道怎么求之后,就要想怎么去写才能实现。数学知识:最大公约数和最小公倍数的乘积等于两个数的乘积,即sum=ab=xy;(a<=b),所以两个数一定可以被sum整除 ;此时我们知道,两个数中最小数一定小于sqrt(a,b)或sqrt(xy);然后我们可以想想,假如ab(x*y)已知,我们就只需要找他们的因子(就是除自身外能被他整除的数(包括1)),即从1开始遍历,然后找因子,然后再有个判断最大公约数的公式即可判断

三、代码实现+注释

(1).第一种思想
#include <bits/stdc++.h>
#include<algorithm>
using namespace std;
int main()
{
	long long n,m,cnt=0;
	cin>>m>>n;
	//当最大公约数=最小公倍数,那交换两个数答案是一样的,例如:10 10;
	if(m==n) cnt--;
	for(long long i=1;i<=sqrt(n*m);i++)
	{
	//如果i能被整除并且i带进去能够满足__gcd(),就说明找到了一对数
		if(n*m%i==0&&__gcd(i,n*m/i)==m)
		{
		//因为最大公约数和最大公倍数交换位置的时候也成立;
			cnt+=2;
		}
	}
	cout<<cnt;
    return 0;
}

(2)第二种思路:
#include <bits/stdc++.h>
using namespace std;
#define ll long long
ll gcd(ll i,ll j)
{
	if(i%j==0) return j;
	else return gcd(j,i%j);
}
int main()
{
	ll m,n,cnt=0;
	cin>>m>>n;
	//因为m为最大公约数,自然是最小的,而最大的就是最小公倍数n,直接遍历
	for(ll i=m;i<=n;i++)
	{
	//i*j==m*n;
		ll j=m*n/i;
		if(gcd(i,j)==m&&i*j/gcd(i,j)==n)
		{
		//只要满足一次就加一次,注意不是加两次,因为这次是直接整体遍历,他会遍历到另一部分的
			cnt+=1;
		}
	}
	cout<<cnt;
    return 0;
}

四、总结:

总的来说,这个题主要就是考最大公约数和最小公倍数的求法,以及相关函数的运算,建议大家先自己模拟函数,不要一上来就直接用c++的库函数,模拟算法可以训练自己的思维能力

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值