综合实践九1002找新朋友AC

13 篇文章 0 订阅

找新朋友

Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other)
Total Submission(s) : 206   Accepted Submission(s) : 114
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
  
  
2 25608 24027
 

Sample Output
  
  
7680 16016
超时答案
#include<iostream> using namespace std; int gcd(int a, int b) { if (a < b) { int c = a; a = b; b = c; } return (a%b == 0) ? b : gcd(b, a%b); } int main() { int n,a,b,i,N; cin >> n; while (n--) { int count = 0; cin >> N; for (int i = 1; i < N; i++) if (gcd(i, N) == 1) count++; cout << count << endl; } system("pause"); return 0; }
以上答案超时,看到一个博客的解析很好
@梦小白 http://blog.csdn.net/qq_15096707/article/details/43310023?locationNum=9&fps=1
以下为博主原文:

 首先读者可能会想:首先创建一个计数器count,从1到N-1编号将每个数均与N判断是否存在公约数,如果不存在公约数则count加1,即新朋友的数量加1。

Java语言编写程序,代码可能结果如下:

[java]  view plain  copy
  1. import java.util.*;  
  2.   
  3. public class Main1079a {  
  4.   
  5.     public static void main(String[] args) {  
  6.         // TODO Auto-generated method stub  
  7.         Scanner input = new Scanner(System.in);  
  8.         int cn = input.nextInt();  
  9.         for(int i = 0; i < cn; i++) {  
  10.             int n = input.nextInt();  
  11.             int num = n - 1;//除去本身  
  12.             if(n % 2 == 0) {  
  13.                 num = num - (n - 2) / 2;//除去那些与编号N有公约数2的编号  
  14.                 for(int j = 1; j < n; j += 2) {  
  15.                     //判断两数是否存在公约数  
  16.                     if(isExistGcd(j, n))  
  17.                         num -= 1;  
  18.                 }  
  19.             }  
  20.             else {  
  21.                 for(int j = 1; j < n; j++) {  
  22.                     if(isExistGcd(j, n))  
  23.                         num -= 1;  
  24.                 }  
  25.             }  
  26.             System.out.println(num);  
  27.         }  
  28.     }  
  29.       
  30.     public static boolean isExistGcd(int a, int b) {  
  31.         for(int i = 2; i <= a && i <= b; i++) {  
  32.             if(a % i == 0 && b % i == 0)  
  33.                 return true;  
  34.         }  
  35.         return false;  
  36.     }  
  37. }  

       聪明的读者可能已经发现,这样的程序效率很低,以至于系统会提示时间超限。(我还没提交过,感觉会超限)
那么,为了提高效率,我们可以采取类似”筛法求素数“的过程,首先将创建一个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语言编写程序,代码如下:

[java]  view plain  copy
  1. import java.util.Scanner;  
  2.   
  3. public class Main1079b {  
  4.   
  5.     public static void main(String[] args) {  
  6.         // TODO Auto-generated method stub  
  7.         Scanner input = new Scanner(System.in);  
  8.         int cn = input.nextInt();  
  9.         for(int i = 0; i < cn; i++) {  
  10.             int n = input.nextInt();  
  11.             //创建数组,并初始化为false。  
  12.             //该数组中的下标表示对应的编号,数组的值表示与会长的关系。true为老朋友,false为新朋友  
  13.             boolean people[] = new boolean[n];  
  14.             for(int j = 0; j < n; j++)  
  15.                 people[j] = false;  
  16.               
  17.             int num = 0;  
  18.             for(int j = 2; j <= n / 2; j++) {  
  19.                 //标记与N有公约数的下标,赋值为true  
  20.                 if(n % j == 0 && people[j] == false) {  
  21.                     for(int k = j; k < n; k += j) {  
  22.                         people[k] = true;  
  23.                     }  
  24.                 }  
  25.             }  
  26.               
  27.             //计算新朋友的个数  
  28.             for(int j = 1; j < n; j++)  
  29.                 if(people[j] == false)  
  30.                     num++;  
  31.             System.out.println(num);  
  32.         }  
  33.     }  
  34.   
  35. }  
但博主的代码不是很简洁
另外一个博主的代码很简洁
@
  1. http://www.cnblogs.com/chuanlong/archive/2012/10/18/2728893.html  
         
         
  1. <pre name="code" class="cpp">#include <stdio.h>  
  2. #include <string>  
  3. #define MAXN 32768  
  4. int a[MAXN + 5];  
  5. int main()  
  6. {  
  7.     int i, j, k, CN, num, count;  
  8.     scanf("%d", &CN);  
  9.     while (CN--)  
  10.     {  
  11.         //initialize the array  
  12.         memset(a, 0, sizeof(a));  
  13.         scanf("%d", &num);  
  14.         //if the number have common divisor with the input, make the value = 1  
  15.         for (j = 2; j < num; j++)          
  16.             if (num % j == 0)  
  17.                 for (k = j; k < num; k += j)  
  18.                     a[k] = 1;  
  19.         count = 0;  
  20.         //numbers of zero is numbers of new friends, pay attention to k = 1  
  21.         for (k = 1; k < num; k++)  
  22.             if (a[k] == 0)  
  23.                 count++;  
  24.         printf("%d\n", count);  
  25.     }  
  26. }  

       
       
编译错误,不知道怎么通过。。。
总结:编译错误可能就是格式上的问题或者写法虽然能运行出来,但是和这种语言不兼容的,所以换一种写法试试o(^▽^)o
  1. #include<iostream>
  2. using namespace std;
  3. const int MAXN = 32768;
  4. int arr[MAXN + 5];
  5. int main()
  6. {
  7. int n,i,j,N;
  8. cin >> n;
  9. while (n--)
  10. {
  11. for (i = 0; i < MAXN; i++)
  12. arr[i] = 0;//数组全部初始化为0
  13. int count = 0;
  14. cin >> N;
  15. for (i = 2; i < N; i++)
  16. if (N % i == 0)
  17. for (j = i;j < N;j += i)//比如N%2==0,那么将2,2+2,2+2+2,。。。全记为1,然后3,5,7。。。
  18. arr[j] = 1;
  19. for (i = 1;i<N;i++)
  20. if (arr[i] == 0)
  21. count++;
  22. cout << count << endl;
  23. }
  24. //system("pause");
  25. return 0;}
  26.   
YEAH!
( •̀ ω •́ )y!!
AC!!!
*★,°*:.☆\( ̄▽ ̄)/$:*.°★*
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值