P a r t Part Part 1 1 1 读题
两个或多个整数共有约数中最大的一个叫做它们的最大公约数。
两个或多个整数公有的倍数叫做它们的公倍数,其中除 0 0 0以外最小的一个公倍数就叫做这几个整数的最小公倍数。
现在有两个整数 a a a, b b b( 2 ≤ a ≤ 100000 2≤a≤100000 2≤a≤100000, 2 ≤ b ≤ 1000000 2≤b≤1000000 2≤b≤1000000),求出满足下列两个条件的所有 P P P, Q Q Q的个数,条件:
1. P 1.P 1.P, Q Q Q是正整数;
2. 2. 2.要求 P P P, Q Q Q以 a a a为最大公约数,以 b b b为最小公倍数。
输入格式
输入一行,包含两个数 a a a、 b b b, a a a、 b b b之间用空格隔开。
输出格式
输出一行,包含一个数,为满足条件的所有 P P P, Q Q Q( P P P, Q Q Q为正整数)的个数,若不满足条件则个数为 0 0 0。
输入样例
3 60
输出样例
4
样例说明
此时的 P P P、 Q Q Q分别为: [ 3 , 60 ] [3,60] [3,60] [ 12 , 15 ] [12,15] [12,15] [ 15 , 12 ] [15,12] [15,12] [ 60 , 3 ] [60,3] [60,3]
故答案为 4 4 4
数据范围与提示
对于 100 100% 100的数据, 2 ≤ a ≤ 100000 2≤a≤100000 2≤a≤100000, 2 ≤ b ≤ 1000000 2≤b≤1000000 2≤b≤1000000
P a r t Part Part 2 2 2 思路
看到题目,我们就在想这个题需要求最大公约数,然后进行计算,这里我提供两种计算方法。
方法1:直接计算(常用,即辗转相除法)
int gcd(int a,int b){
if(b==0)return a;
return gcd(b,a%b);
}
方法2:使用 < n u m e r i c > <numeric> <numeric>库,自带 g c d gcd gcd(最大公约数)和 l c m lcm lcm(最小公倍数),(万能头有这个库)
#include<bits/stdc++.h>
using namespace std;
int main(){
int a,b,gd,lm;
cin>>a>>b;
gd=gcd(a,b);
lm=lcm(a,b);
cout<<gd<<" "<<lm;
return 0;
}
我们知道 l c m = a ÷ g c d × b lcm=a÷gcd\times b lcm=a÷gcd×b,这就相当于已知 l c m lcm lcm和 g c d gcd gcd,求 a a a和 b b b, 即 l c m × g c d = a × b lcm\times gcd=a\times b lcm×gcd=a×b。
所以我们可以从 l c m lcm lcm开始一直枚举到 g c d gcd gcd,当 l c m × g c d % a lcm\times gcd\%a lcm×gcd%a不等于 0 0 0时(也就是说没有与 a a a对应的时候),我们直接跳过,否则我们建立一个变量 j = l c m × g c d ÷ a j=lcm\times gcd÷a j=lcm×gcd÷a,然后我们判断:如果 i i i和 j j j的最大公约数是 g c d gcd gcd,就可以加 1 1 1。也就是如下写法:
写法1
int m=a*b;//m就是两数乘积,即lcm*gcd
for(int i=a;i<=b;i++){
if(m%i!=0)continue;//跳过环节
int j=m/i;
if(a==gcd(i,j))s++;//s是计数器
}
相比起写法1来说,我们可以更简单一些,也就是说不进行跳过环节,我们就得到了如下写法:
写法2(比起写法1来说更简明一些,省去了跳过环节)
for(int i=a;i<=b;i++)if((a*b)%i==0&&gcd(i,(a*b)/i)==a)s++;//s是计数器
小tip:大家可以先根据思路,写一下代码哦!
P a r t Part Part 3 3 3 代码
注意!!!以下部分我均采用方法1求 g c d gcd gcd,想使用方法2的自行上划
写法1
#include<bits/stdc++.h>
using namespace std;
int gcd(int a,int b){
if(b==0)return a;
return gcd(b,a%b);
}
int a,b,s;
int main(){
cin>>a>>b;
int m=a*b;
for(int i=a;i<=b;i++){
if(m%i!=0)continue;
int j=m/i;
if(a==gcd(i,j))s++;
}
cout<<s<<endl;
return 0;
}
写法2
#include<bits/stdc++.h>
using namespace std;
int gcd(int a,int b){
if(b==0)return a;
return gcd(b,a%b);
}
int a,b,s;
int main(){
cin>>a>>b;
for(int i=a;i<=b;i++)if((a*b)%i==0&&gcd(i,(a*b)/i)==a)s++;
//根据公式a/gcd*b=lcm可以推出
cout<<s;
return 0;
}
听完后,是不是觉得很简单呢?赶快自己去试一下吧!!!