P1029 [NOIP 2001 普及组] 最大公约数和最小公倍数问题
P1029 [NOIP 2001 普及组] 最大公约数和最小公倍数问题
题目描述
输入两个正整数 \(x_0, y_0\),求出满足下列条件的 \(P, Q\) 的个数:
-
\(P,Q\) 是正整数。
-
要求 \(P, Q\) 以 \(x_0\) 为最大公约数,以 \(y_0\) 为最小公倍数。
试求:满足条件的所有可能的 \(P, Q\) 的个数。
输入格式
一行两个正整数 \(x_0, y_0\)。
输出格式
一行一个数,表示求出满足条件的 \(P, Q\) 的个数。
输入输出样例 #1
输入 #1
3 60
输出 #1
4
说明/提示
\(P,Q\) 有 \(4\) 种:
- \(3, 60\)。
- \(15, 12\)。
- \(12, 15\)。
- \(60, 3\)。
对于 \(100\%\) 的数据,\(2 \le x_0, y_0 \le {10}^5\)。
【题目来源】
NOIP 2001 普及组第二题
本题题面非常简洁,首先我们来回顾一下本题需要用到的关于最大公约数的性质:
\(ab=(a,b)[a,b]\)
这条性质非常神奇。有了这条性质,我们先枚举 \(x_0y_0\) 的因数 \(i\) ,然后判断条件累加结果即可。但是有一种特殊情况:如果 \(x_0=y_0\) ,那么答案就要 \(-1\) ,因为每次循环如果 \(i\) 是\(x_0y_0\) 的因数,就会判断 \((i,\frac{x_0y_0}{i})\) 是否为 \(x_0\) ,如果符合条件答案就会 \(+2\) ,因为可以把 \(x,y\) 颠倒,也算一种答案。当 \(i\) 枚举到 \(\sqrt{x_0y_0}\) (或者说是 \(x_0\) 或 \(y_0\) )时, \(i=\frac{x_0y_0}{i}=x_0=y_0\) ,答案就会多 \(1\) ,所以要特判一下。代码如下:
点击查看代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
ll a,b,t,s;//十年OI一场空,______________________
ll gcd(ll x,ll y){
return y?gcd(y,x%y):x;//手写gcd,虽然速度跟库函数__gcd差不多,但是可以少打两个下划线
}
int main(){
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
cin>>a>>b;
t=a*b;
if(a==b)s--;//特判
for(ll i=a;i*i<=t;i++){//i从a开始枚举
if(t%i==0&&gcd(i,t/i)==a)s+=2;
}
cout<<s;
return 0;
}
做完这道题可以去尝试一下P1072 [NOIP 2009 提高组] Hankson 的趣味题,跟这题思路很相似。

浙公网安备 33010602011771号