P1029 [NOIP 2001 普及组] 最大公约数和最小公倍数问题

P1029 [NOIP 2001 普及组] 最大公约数和最小公倍数问题

题目描述

输入两个正整数 \(x_0, y_0\),求出满足下列条件的 \(P, Q\) 的个数:

  1. \(P,Q\) 是正整数。

  2. 要求 \(P, Q\)\(x_0\) 为最大公约数,以 \(y_0\) 为最小公倍数。

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

输入格式

一行两个正整数 \(x_0, y_0\)

输出格式

一行一个数,表示求出满足条件的 \(P, Q\) 的个数。

输入输出样例 #1

输入 #1

3 60

输出 #1

4

说明/提示

\(P,Q\)\(4\) 种:

  1. \(3, 60\)
  2. \(15, 12\)
  3. \(12, 15\)
  4. \(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 的趣味题,跟这题思路很相似。

posted @ 2025-08-16 18:30  Wenze_Li  阅读(10)  评论(0)    收藏  举报