Description
给定正整数n,有多少个小于等于n的正整数与n互质,两个数互质的条件为两个数只有1这个共同的因子.
Input
多组测试数据,每组仅一行,为正整数n.(n<=100000)
Output
对于每组数据输出有多少个与n互质的数
Sample Input
9
Sample Output
6
解析一:欧拉函数
#include <stdio.h>
int eulerFunction(int n) {
int result = n;//表示初始的欧拉函数值 ,表示初始时用于n互质的数的个数为n
for (int i = 2; i * i <= n; i++) {
if (n % i == 0) {
while (n % i == 0) {
n /= i;
}
result -= result / i;
}
}
if (n > 1) {
result -= result / n;
}
return result;
}
int main() {
int n;
while (scanf("%d", &n) != EOF) {
int count = eulerFunction(n);
printf("%d\n", count);
}
return 0;
}
当我们计算一个数 n 的欧拉函数时,我们需要找到小于等于 n 的所有与 n 互质的数的个数。代码中的算法通过遍历 n 的质因数来计算欧拉函数的值。下面是算法的详细解释:
- 首先,我们初始化一个变量 result 为 n,表示初始时与 n 互质的数的个数为 n。
- 然后,我们从 2 开始遍历到 sqrt(n)(平方根),对于每个数字 i,我们判断它是否是 n 的质因数(即 n 能被 i 整除)。
- 如果 i 是 n 的质因数,那么我们执行以下操作:
- 将 result 减去 result / i,这是因为我们要去除与 i 相关的质因数的贡献。例如,如果 n=12,i=2,那么 2 是 12 的质因数,12 中有两个 2 因子,即 223=12,所以与 2 相关的质因数的贡献为 2/2=1,我们要将 result 减去这个贡献。
- 然后,我们通过不断将 n 除以 i,去除 n 中所有的 i 因子。这样做是为了确保我们只计算每个质因数的贡献一次。例如,对于 n=12,我们先除以 2,得到 n=6,然后再除以 2,得到 n=3,这样我们就去除了所有的 2 因子。
- 如果 n 大于 1,说明 n 是一个大于 sqrt(n) 的质因数,那么我们将 result 减去 result / n 的贡献。这是因为 n 是一个大于 sqrt(n) 的质因数,所以它的贡献还没有被计算过。
- 最后,我们返回最终的 result 值,即为欧拉函数的计算结果。
通过以上步骤,我们可以计算出给定数 n 的欧拉函数的值。代码中的 while 循环用于读取用户输入的整数 n,并计算对应的欧拉函数值,然后输出结果。直到用户输入的整数为 EOF(文件结束标志)时,程序才会退出
解析二.最大公因数
#include <stdio.h>
int gcd(int a, int b) {
if (b == 0) {
return a;
}
return gcd(b, a % b);
}
int main() {
int n;
while (scanf("%d", &n) != EOF) {
int count = 0;
for (int i = 1; i <= n; i++) {
if (gcd(i, n) == 1) {
count++;
}
}
printf("%d\n", count);
}
return 0;
}
这段代码是一个计算欧拉函数的示例程序。让我逐步解释它的功能。
-
首先,代码包含了一个名为
gcd
的函数,用于计算两个数的最大公约数。它使用了欧几里得算法来实现。如果其中一个数为 0,则返回另一个数作为最大公约数;否则,递归地调用gcd
函数,将第二个数和两个数相除的余数作为参数。 -
在
main
函数中,代码使用了一个循环来读取输入的整数 n,直到遇到文件结束符为止(EOF)。每次读取一个整数 n 后,都会执行以下操作:a. 初始化一个变量
count
,用于记录与 n 互质的数的个数。b. 使用一个循环从 1 到 n 遍历所有可能的数 i。
c. 对于每个数 i,调用
gcd(i, n)
函数来计算 i 和 n 的最大公约数。如果最大公约数为 1,说明 i 和 n 是互质的,将count
值加一。d. 循环结束后,输出
count
的值,即与 n 互质的数的个数。 -
程序继续读取下一个整数 n,并重复执行上述步骤,直到遇到文件结束符为止。
这个程序的目的是计算给定