Problem Description
新年快到了,“猪头帮协会”准备搞一个聚会,已经知道现有会员N人,把会员从1到N编号,其中会长的号码是N号,凡是和会长是老朋友的,那么该会员的号码肯定和N有大于1的公约数,否则都是新朋友,现在会长想知道究竟有几个新朋友?请你编程序帮会长计算出来。
Input
第一行是测试数据的组数CN(Case number,1<CN<10000),接着有CN行正整数N(1<n<32768),表示会员人数。
Output
对于每一个N,输出一行新朋友的人数,这样共有CN行输出。
Sample Input
新年快到了,“猪头帮协会”准备搞一个聚会,已经知道现有会员N人,把会员从1到N编号,其中会长的号码是N号,凡是和会长是老朋友的,那么该会员的号码肯定和N有大于1的公约数,否则都是新朋友,现在会长想知道究竟有几个新朋友?请你编程序帮会长计算出来。
Input
第一行是测试数据的组数CN(Case number,1<CN<10000),接着有CN行正整数N(1<n<32768),表示会员人数。
Output
对于每一个N,输出一行新朋友的人数,这样共有CN行输出。
Sample Input
2
25608
24027
Sample Output
7680
16016
//方法一,辗转相除法求最大公约数(time exceed error)
/*
#include"stdio.h"
int compute(int a, int b) {
if (b == 0) return a;
else return compute(b, a%b);
}
int main() {
int times;
scanf("%d", ×);
while (times--) {
unsigned int num, count = 0;
scanf("%u", &num);
for (int i = 2; i < num; i++) {
int gcd = compute(num, i);
if (gcd > 1) count++;
}
printf("%d\n", num-count-1);
}
return 0;
}*/
问题求解 -> 欧拉函数(公式自行百度)
#include"stdio.h"
#include"math.h"
int count(int num) {
int res = num;
for (int i = 2; i <= sqrt(num); i++) { //求出n的小于sqrt(n)的质因数,大于sqrt(n)的最多只有一个;
if (num % i == 0) res = res/i*(i-1); //sqrt()是在优化算法
while (num % i == 0) {
num /= i;
}
}
if (num > 1) { //意味着有大于sqrt(n) 的因子
res = res / num * (num-1);
}
return res;
}
int main() {
int cn;
scanf("%d", &cn);
while (cn--) {
int num;
scanf("%d", &num);
int result = count(num);
printf("%d\n", result);
}
return 0;
}