题目描述
输入两个正整数 ,求出满足下列条件的 的个数:
- 是正整数。
- 要求 以 为最大公约数,以 为最小公倍数。
试求:满足条件的所有可能的 的个数。
输入格式
一行两个正整数 。
输出格式
一行一个数,表示求出满足条件的 的个数。
输入输出样例
输入 #1 复制
3 60
输出 #1 复制
4
说明/提示
有 种:
- 。
- 。
- 。
- 。
对于 的数据, 。
思路
题意应该很明确,就是找一对数,使它们的最小公约数是
,最大公倍数是
然后,还有一点,就是小学数学(我已经初一了)里面的一个公式:
意思就是,两个数的最大公约数和最小公倍数的积就是这两个数的积
可以这样来理解:
这样的话
① ② ③ ②
② ① ② ③
这样就可以理解了,所以,只要枚举一个数,另一个数就可以算出来。
然后,求最大公约数还有一种很快的方法:辗转相除法
比如说求
和
的最大公约数:
这样除到 为止
证明:
假设 , 的最大公约数就是
则 ,问题就转换成了求 和 的最大公约数
以此类推,无论怎么模,余数始终是 的倍数,这样一步步算下来,最后当余数为 时, 就是这两个数的最大公约数
这样,所有问题就都解决了
代码
#include<bits/stdc++.h>
using namespace std;
int m,n,ans;
int zj(int x,int y)//不要在意这个函数名
{
int z;
while(y!=0){//辗转相除法
z=x%y;
x=y;
y=z;
}
return x;
}
int main()
{
cin>>n>>m;
for(register int i=n;i<=m;i++)//因为P,Q一定比最大公约数大,比最小公倍数小
if(n*m%i==0&&zj(i,n*m/i)==n)//符合要求
ans++;
cout<<ans;
return 0;
}