新年快到了,天勤准备搞一个聚会,已经知道现有会员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; } }
如果编号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); } } }