题目描述
输入两个正整数x0,y0,求出满足下列条件的P,Q 的个数:
1.P,Q 是正整数。
2.要求 P,Q 以x0 为最大公约数,以y0 为最小公倍数。
试求:满足条件的所有可能的P,Q 的个数。
输入格式
一行两个正整数 x0,y0。
输出格式
一行一个数,表示求出满足条件的 P,Q 的个数。
输入输出样例
输入 #1复制
3 60
输出 #1复制
4
说明/提示
P,Q 有 4 种:
- 3,60。
- 15,12。
- 12,15。
- 60,3。
解答
#include<stdio.h>
int gcd(int a, int b) {
while (b != 0) {
int c = b;
b = a % b;
a = c;
}return a;
}
int main() {
int P, Q;
scanf("%d %d", &P, &Q);
int count = 0;
int x0 = gcd(P, Q);
int y0 = P * Q / x0;
for (int i = x0 ; i <= y0; i++) {
if (P * Q % i == 0) {
if (gcd(i, P * Q / i) == P) {
count++;
}
}
}
printf("%d\n", count);
return 0;
}
接下来逐行分析
首先定义了一个名为 gcd
的函数,使用欧几里德算法(辗转相除法)用于计算两个整数的最大公约数,
#include<stdio.h>
int gcd(int a, int b) {
while (b != 0) {
int c = b;
b = a % b;
a = c;
}return a;
}
接下来输入P,Q。使用 scanf
函数 从标准输入读取两个整数值 并将它们存储在 P
和 Q
中。
定义一个整数变量 count
,用于存储计数结果。
调用 gcd
函数来计算 P
和 Q
的最大公约数,将结果存储在 x0
中。我们计算 y0
,它是 P
和 Q
的乘积除以它们的最大公约数。(此处运用到了一个数学知识)
int main() {
int P, Q;
scanf("%d %d", &P, &Q);
int count = 0;
int x0 = gcd(P, Q);
int y0 = P * Q / x0;
这是一个 for
循环,它从 P
开始遍历到 Q
。
在每次迭代中,我们首先检查 P
与 Q
的乘积除以 i的余数
是否等于0,这意味着 i
是它们的一个因子。
然后,我们使用 gcd
函数来计算 i
和 P * Q / i
的最大公约数,如果结果等于 P
,则递增 count
,表示我们找到了一个满足条件的因子。
for (int i = x0 ; i <= y0; i++) {
if (P * Q % i == 0) {
if (gcd(i, P * Q / i) == P) {
count++;
}
}
}
printf("%d\n", count);
return 0;
}
分析到这里就结束了。
不过要注意的是
如果把
if (gcd(i, P * Q / i) == P) {
换成
if (gcd(i, P * Q / i) == x0) {
然后再洛谷上就会WA。
实际上替换以后更合理,简单的讲就是
运行替换前的代码,以输入12 15为例,在VS上输出0(错误);在洛谷上能AC
运行替换后的代码,还是以输入12 15为例,在VS上输出4(正确);反而这在洛谷上WA
对于这个现象,个人的理解是,这一组P Q有4对,输入样例是3 60这对,我只需要确保每组数当中,输入数字相差最大的那对 能满足即可