zoukankan      html  css  js  c++  java
  • 九度oj 题目1087:约数的个数

    题目描述:

    输入n个整数,依次输出每个数的约数的个数

    输入:

    输入的第一行为N,即数组的个数(N<=1000)
    接下来的1行包括N个整数,其中每个数的范围为(1<=Num<=1000000000)
    当N=0时输入结束。

    输出:

    可能有多组输入数据,对于每组输入数据,
    输出N行,其中每一行对应上面的一个数的约数的个数。

    样例输入:
    5
    1 3 4 6 12
    样例输出:
    1
    2
    3
    4
    6
     1 #include <cstdio>
     2 #include <cstdlib>
     3 #include <cstring>
     4 #include <string>
     5 #include <cmath>
     6 
     7 long long int cal(long long int num) {
     8     if(num == 1) {
     9         return 1;
    10     }
    11     long long ans = 2;
    12     long long int middle = sqrt(num);
    13     if(middle * middle == num) {
    14         ans++;
    15     }
    16     else {
    17         middle++;
    18     }
    19     for(long long int i = 2; i < middle; i++) {
    20         if(num % i == 0) {
    21             ans = ans + 2;
    22         }
    23     }
    24     return ans;
    25 }
    26 
    27 int main(int argc, char const *argv[])
    28 {
    29     int N;
    30     long long int num;
    31     scanf("%d",&N);
    32     while(N != 0) {
    33         for(int i = 0; i < N; i++) {
    34             scanf("%lld",&num);
    35             long long res = cal(num);
    36             printf("%lld
    ",res);
    37         }
    38         scanf("%d",&N);
    39     }
    40     return 0;
    41 }

    题目不难,但要注意特殊情况以及取值范围,int的最大值大概是2的9次方

    ----9-17更新

    题目其实并没有超过int的范围

     1 #include <cstdio>
     2 #include <cstdlib>
     3 #include <cstring>
     4 #include <string>
     5 #include <cmath>
     6 
     7 int cal(long long int num) {
     8     if(num == 1) {
     9         return 1;
    10     }
    11     int ans = 0;
    12     int middle = sqrt(num);
    13     for(int i = 1; i <= middle; i++) {
    14         if(num % i == 0) {
    15             ans = ans + 2;
    16         }
    17     }
    18     if(middle*middle == num) {
    19         ans--;
    20     }
    21     return ans;
    22 }
    23 
    24 int main(int argc, char const *argv[])
    25 {
    26     int N;
    27     int num;
    28     scanf("%d",&N);
    29     while(N != 0) {
    30         for(int i = 0; i < N; i++) {
    31             scanf("%d",&num);
    32             int res = cal(num);
    33             printf("%d
    ",res);
    34         }
    35         scanf("%d",&N);
    36     }
    37     return 0;
    38 }

    还有另一种更快的方法是

    对于一个数n

    n可以写成几个素数的ai次方的乘积

    则n的约数个数为(a1+1)*(a2+1)*(a3+1)*...

    实验了一下这个方法,开始还想着去求素数,再一个个的比较,代码如下

     1 #include <cstdio>
     2 #include <cstdlib>
     3 #include <cstring>
     4 #include <string>
     5 #include <cmath>
     6 #define Prime_Cnt 1002
     7  
     8 int prime[1002];
     9 int fp[1002];
    10 int cnt[1002];
    11  
    12 int getPrime() {
    13     memset(fp, 0, sizeof(fp));
    14     int p = 0;
    15     for(int i = 2; i < Prime_Cnt; i++) {
    16         if(fp[i] == 0) {
    17             prime[p++] = i;
    18             for(int j = 2*i; j < Prime_Cnt; j+=i) {
    19                 fp[j] = 1;
    20             }
    21         }
    22     }
    23     return p;
    24 } 
    25  
    26 int cal(int n, int p) {
    27     if(n == 1) {
    28         return 1;
    29     }
    30     memset(cnt, 0, sizeof(cnt));
    31     int i = 0;
    32     int ans = 1;
    33     while(n != 1) {
    34         int tmp = 0;
    35         while(n%prime[i] != 0) {
    36             i++;
    37         }
    38         while(n%prime[i] == 0) {
    39             n = n/prime[i];
    40             tmp++;
    41         }
    42         ans = ans *(tmp+1);
    43         cnt[i] = tmp;
    44     }
    45     return ans;
    46 }
    47  
    48  
    49 int main(int argc, char const *argv[])
    50 {
    51     int N;
    52     int num;
    53     int p = getPrime();
    54     while(scanf("%d",&N) != EOF && N != 0) {
    55         for(int i = 0; i < N; i++) {
    56             scanf("%d",&num);
    57             int ans = cal(num, p);
    58             printf("%d
    ", ans);
    59         }
    60  
    61     }
    62     return 0;
    63 }

    但runtime error

    后来发现可以有不求素数的办法

    代码如下

     1 #include <cstdio>
     2 #include <cstdlib>
     3 #include <cstring>
     4 #include <string>
     5  
     6 int cal(int n) {
     7     if(n == 1) {
     8         return 1;
     9     }
    10     int i = 2;
    11     int ans = 1;
    12     while(n != 1) {
    13         int tmp = 0;
    14         while(n%i != 0) {
    15             i++;
    16         }
    17         while(n%i == 0) {
    18             n = n/i;
    19             tmp++;
    20         }
    21         ans = ans *(tmp+1);
    22     }
    23     return ans;
    24 }
    25  
    26  
    27 int main(int argc, char const *argv[])
    28 {
    29     int N;
    30     int num;
    31     while(scanf("%d",&N) != EOF && N != 0) {
    32         for(int i = 0; i < N; i++) {
    33             scanf("%d",&num);
    34             int ans = cal(num);
    35             printf("%d
    ", ans);
    36         }
    37  
    38     }
    39     return 0;
    40 }

    但时间反而更长了,不知道为啥

    最后看了看大神的代码,是这样写的:

     1 #include <cstdio>
     2 #include <cstdlib>
     3 #include <cstring>
     4 #include <string>
     5 
     6 
     7 int main(int argc, char const *argv[])
     8 {
     9     int N;
    10     int n;
    11     while(scanf("%d",&N) != EOF && N != 0) {
    12         while(N--) {
    13             scanf("%d",&n);
    14             int i = 2;
    15             int ans = 1;
    16             
    17             for(; i*i <= n; i++) {
    18                 if(n % i == 0) {
    19                     int tmp = 1;
    20                     while(n%i == 0) {
    21                         tmp++;
    22                         n=n/i;
    23                     }
    24                     ans = ans*tmp;
    25                 }
    26             }
    27             if(n > 1) ans = ans*2;
    28             printf("%d
    ", ans);
    29         }
    30 
    31     }
    32     return 0;
    33 }

     第27行的意思是如果退出时还没有除尽的话,那么也就剩下最后一个素数了,所以ans = ans * 2

    自己写了一个代码如下

     1 #include <cstdio>
     2 #include <cstdlib>
     3 #include <cstring>
     4 #include <string>
     5 #include <cmath>
     6 
     7 
     8 int main(int argc, char const *argv[])
     9 {
    10     int N;
    11     int n;
    12     while(scanf("%d",&N) != EOF && N != 0) {
    13         while(N--) {
    14             scanf("%d",&n);
    15             int i = 2;
    16             int ans = 1;
    17             int q = sqrt(n);
    18             while(n != 1) {
    19                 int tmp = 1;
    20                 while(n % i == 0) {
    21                     n = n/i;
    22                     tmp++;
    23                 }
    24                 
    25                 ans = ans * tmp;
    26                 if(i == q+1) {
    27                     break;
    28                 }
    29                 i++;
    30             }
    31             if(n != 1) {
    32                 ans = ans * 2;
    33             }
    34             printf("%d
    ", ans);
    35         }
    36 
    37     }
    38     return 0;
    39 }
  • 相关阅读:
    JS中常见的几种控制台台报错
    nssm常用命令(在Windows系统下安装服务的工具)
    Web前端浏览器默认样式重置(CSS Tools: Reset CSS)
    Layui的本地存储方法-Layui.data的基本使用
    JS事件冒泡与事件捕获怎么理解?
    解决Web开发HTML页面中footer保持在页面底部问题
    cpdetector获取文件编码
    maven
    jdom工具类
    httpclient4封装类
  • 原文地址:https://www.cnblogs.com/jasonJie/p/5682403.html
Copyright © 2011-2022 走看看