用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-03-23 22:36:32 浏览: 68
下面是一份 C 语言代码,用于解决这个问题:
```c
#include <stdio.h>
int gcd(int a, int b) {
if (b == 0) {
return a;
} else {
return gcd(b, a % b);
}
}
int lcm(int a, int b) {
return a / gcd(a, b) * b;
}
int main() {
int n, a0, a1, b0, b1;
int x, count;
scanf("%d", &n);
while (n--) {
scanf("%d%d%d%d", &a0, &a1, &b0, &b1);
if (b1 % a1 != 0 || a0 % a1 != 0 || b0 % (b1 / a1) != 0) {
printf("0\n");
continue;
}
int y = b1 / a1;
int z = a0 / a1;
int w = b0 / y;
int g = gcd(z, gcd(y, w));
z /= g;
y /= g;
w /= g;
count = 0;
for (x = 1; x <= g; x++) {
if (gcd(x, z) == 1 && lcm(x, w) == y) {
count++;
}
}
printf("%d\n", count);
}
return 0;
}
```
代码中使用了 `gcd` 函数求最大公约数,使用了 `lcm` 函数求最小公倍数。在 `main` 函数中,通过循环读入每组数据。对于每组数据,我们首先检查是否存在满足条件的 $x$,如果不满足,直接输出 0。如果满足条件,我们可以将问题化简为:求解一个关于 $x$ 的同余方程 $ax \equiv b \pmod{m}$ 的解的个数,其中 $a = z$,$b = 1$,$m = w$。这个问题可以使用扩展欧几里得算法求解。
时间复杂度为 $O(n \log n)$,可以通过本题。
阅读全文