1079:找新朋友 分数:1
标签
- 简单数学题
- 公约数
题目描述
新年快到了,天勤准备搞一个聚会,已经知道现有会员N人,把会员从1到N编号,其中会长的号码是N号,凡是和会长是老朋友的,那么该会员的号码肯定和N有大于1的公约数,否则都是新朋友,现在会长想知道究竟有几个新朋友?请你编程序帮会长计算出来。
输入格式
第一行是测试数据的组数CN(Case number,1<CN<10000),接着有CN行正整数N(1<n<32768),表示会员人数。
输出
对于每一个N,输出一行新朋友的人数,这样共有CN行输出。
样例输入
2
25608
24027
样例输出
7680
16016
首先读者可能会想:首先创建一个计数器count,从1到N-1编号将每个数均与N判断是否存在公约数,如果不存在公约数则count加1,即新朋友的数量加1。
用java语言编写程序,代码可能结果如下:
import java.util.*;
public class Main1079a {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner input = new Scanner(System.in);
int cn = input.nextInt();
for(int i = 0; i < cn; i++) {
int n = input.nextInt();
int num = n - 1;//除去本身
if(n % 2 == 0) {
num = num - (n - 2) / 2;//除去那些与编号N有公约数2的编号
for(int j = 1; j < n; j += 2) {
//判断两数是否存在公约数
if(isExistGcd(j, n))
num -= 1;
}
}
else {
for(int j = 1; j < n; j++) {
if(isExistGcd(j, n))
num -= 1;
}
}
System.out.println(num);
}
}
public static boolean isExistGcd(int a, int b) {
for(int i = 2; i <= a && i <= b; i++) {
if(a % i == 0 && b % i == 0)
return true;
}
return false;
}
}
聪明的读者可能已经发现,这样的程序效率很低,以至于系统会提示时间超限。(我还没提交过,感觉会超限)
那么,为了提高效率,我们可以采取类似”筛法求素数“的过程,首先将创建一个boolean类型的数组people(数组内所有值初始化为false),表明与会长的关系,如:people[10] = true;表示编号为10的会员是会长的老朋友;people[21] = false;表示编号为21的会员是会长的新朋友。
如果编号N能被2整除,则N与2以及2的倍数有公约数,那么就可以将people数组下标为2、2的倍数的值赋值为true;同样地,判断是否能被3、5、。。。整除。将所有与N有公约数的值赋值为true,计算数组中false值的个数,即为会长新朋友的人数。
用java语言编写程序,代码如下:
import java.util.Scanner;
public class Main1079b {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner input = new Scanner(System.in);
int cn = input.nextInt();
for(int i = 0; i < cn; i++) {
int n = input.nextInt();
//创建数组,并初始化为false。
//该数组中的下标表示对应的编号,数组的值表示与会长的关系。true为老朋友,false为新朋友
boolean people[] = new boolean[n];
for(int j = 0; j < n; j++)
people[j] = false;
int num = 0;
for(int j = 2; j <= n / 2; j++) {
//标记与N有公约数的下标,赋值为true
if(n % j == 0 && people[j] == false) {
for(int k = j; k < n; k += j) {
people[k] = true;
}
}
}
//计算新朋友的个数
for(int j = 1; j < n; j++)
if(people[j] == false)
num++;
System.out.println(num);
}
}
}