写出C语言代码已知正整数 a0,a1,b0,b1,设某未知正整数 x 满足: 1. x 和 a0 的最大公约数是 a1 2. x 和 b0 的最小公倍数是 b1 求解满足条件的 x 的个数。请你帮助他编程求解这个问题。 对于 100%的数据,保证有 1≤a0,a1,b0,b1≤2,000,000,000。 输入格式: 第一行为一个正整数 n,表示有 n 组输入数据。n≤2000 接下来的 n 行每行一组输入数据,为四个正整数 a0,a1,b0,b1,之间用一个空格隔开。 输出格式: 共n 行。每组输入数据的输出结果占一行,为一个整数。 对于每组数据:若不存在这样的 x,请输出 0; 若存在这样的 x,请输出满足条件的 x 的个数;
时间: 2024-01-21 12:19:29 浏览: 108
计算两个正整数的最大公约数C语言代码
以下是一种C语言的解法:
```c
#include <stdio.h>
// 计算最大公约数
int gcd(int a, int b) {
return b == 0 ? a : gcd(b, a % b);
}
// 计算最小公倍数
int lcm(int a, int b) {
return a / gcd(a, b) * b;
}
int main() {
int n;
scanf("%d", &n);
while (n--) {
int a0, a1, b0, b1;
scanf("%d%d%d%d", &a0, &a1, &b0, &b1);
// 对于a0和b0不存在公因数的情况,x的范围是[a0*b1/a1, a0*b1],每个满足条件的x都可以表示为 k*a0*b1 + a0*b1/a1
if (gcd(a0, b0) == 1) {
int l = a0 * b1 / a1;
int r = a0 * b1;
int cnt = (r - l) / (a0 * b1 / a1) + 1;
printf("%d\n", cnt);
}
// 对于a0和b0存在公因数的情况,先将a0和b0分解质因数成p1^k1 * p2^k2 * ... * pn^kn的形式,对于每个pi,如果ki在a1和b1中出现的次数不同,则无解;否则x的范围是[lcm(a0,b0)*max(a1,b1)/a0, lcm(a0,b0)*min(a1,b1)/b0],每个满足条件的x都可以表示为 k*lcm(a0,b0)*max(a1,b1) + lcm(a0,b0)*max(a1,b1)/a0
else {
int g = gcd(a0, b0);
int a0_ = a0 / g, b0_ = b0 / g;
int a1_ = a1, b1_ = b1;
while (g > 1) {
if (g % a0_ == 0) {
g /= a0_;
a1_ /= a0_;
}
else if (g % b0_ == 0) {
g /= b0_;
b1_ /= b0_;
}
else {
printf("0\n");
break;
}
}
if (g == 1) {
int l = lcm(a0, b0) * (a1_ > b1_ ? a1_ : b1_) / a0;
int r = lcm(a0, b0) * (a1_ < b1_ ? a1_ : b1_) / b0;
int cnt = (r - l) / (lcm(a0, b0) * (a1_ > b1_ ? a1_ : b1_) / a0) + 1;
printf("%d\n", cnt);
}
}
}
return 0;
}
```
时间复杂度:O(n log(max(a0, a1, b0, b1)))
阅读全文