先通过一道例题来看:
输入2个正整数x0,y0(2<=x0<100000,2<=y0<=1000000),求出满足下列条件的P,Q的个数。
条件:
-
P,Q是正整数;
-
要求P,Q以x0为最大公约数,以y0为最小公倍数。
试求:
满足条件的所有可能的两个正整数的个数。
输入
每个测试文件包含不超过5组测试数据,每组两个正整数x0和y0(2<=x0<100000,2<=y0<=1000000)。
输出
对于每组输入数据,输出满足条件的所有可能的两个正整数的个数。
样例输入
3 60
样例输出
4
此时的四种情况分别为:
3 60
15 12
12 15
60 3
解题思路:
第一种就是很常见的思路,辗转相除法
AC代码:
#include<bits/stdc++.h>
#include<math.h>
using namespace std;
const int N = 1e5+10;
int a[N];
int g(int n , int m)
{
int temp , r;
if(n < m)
{
temp = n;
n = m;
m = temp;
}
while(m!=0)
{
r=n%m;
n=m;
m=r;
}
return n;
}
int main()
{
int a , b , res;
while(cin >> a >> b)
{
res = 0;
for(int i = a ; i <= b ; i++)
{
for(int j = i+1 ; j <= b ; j++)
{
if(g(i,j) == a&&i/g(i,j)*j==b)
res++;
}
}
cout << 2*res << endl;
}
return 0;
}
第二种就是辗转相除的递归写法
AC代码:
#include<bits/stdc++.h>
#include<math.h>
using namespace std;
const int N = 1e5+10;
int a[N];
int gcd(int n , int m)
{
int temp , r;
if(n < m)
{
temp = n;
n = m;
m = temp;
}
if(n%m==0)
return m;
else
return gcd(m,n%m);
}
int main()
{
int a , b , res;
while(cin >> a >> b)
{
res = 0;
for(int i = a ; i <= b ; i++)
{
for(int j = i ; j <= b ; j++)
{
if(gcd(i,j) == a&&i/gcd(i,j)*j==b)
res++;
}
}
cout << 2*res << endl;
}
return 0;
}