• hdu 2136 筛法求素数


    题目大意:每个数字都可以表示为一些素数的和,原因很显然:由算数基本定理可知,每一个数都可以表示为素数的乘积,自然也就可以表示为一些素数的和咯。

    于是题目让我们求在这样的表示中出现的最大的素数是第几个素数。

    思路:一开始想都没想,上了一个这样的代码。

     1 #include <algorithm>
     2 #include <cstring>
     3 #include <cstdio>
     4 using namespace std;
     5 
     6 const int N = 1000000;
     7 const int M = 100000;
     8 bool is_prime[N];
     9 int prime[M];
    10 int cnt;
    11 
    12 void sieve()
    13 {
    14     memset( is_prime, 1, sizeof(is_prime) );
    15     is_prime[0] = is_prime[1] = 0;
    16     for ( int i = 2; i < N; i++ )
    17     {
    18         if ( is_prime[i] )
    19         {
    20             int j = i * i;
    21             if ( j >= N ) break;
    22             while ( j < N )
    23             {
    24                 is_prime[j] = 0;
    25                 j += i;
    26             }
    27         }
    28     }
    29     cnt = 0;
    30     for ( int i = 0; i < N; i++ )
    31     {
    32         if ( is_prime[i] )
    33         {
    34             prime[cnt++] = i;
    35         }
    36     }
    37 }
    38 
    39 int solve( int n )
    40 {
    41     if ( n == 1 ) return 0;
    42     int i = 0;
    43     while ( prime[i] * prime[i] <= n )
    44     {
    45         while ( n % prime[i] == 0 )
    46         {
    47             n = n / prime[i];
    48         }        
    49         i++;
    50     }
    51     if ( n == 1 ) return i;
    52     int pos = lower_bound( prime, prime + cnt, n ) - prime;
    53     return pos + 1;
    54 }
    55 
    56 int main()
    57 {
    58     sieve();
    59     int n;
    60     while ( scanf("%d", &n) != EOF )
    61     {
    62         printf("%d
    ", solve(n));
    63     }
    64     return 0;
    65 }

    这个代码是可以过的,不过相对比较慢。

    其实仔细一想,这样写更好。

     1 #include <cstring>
     2 #include <cstdio>
     3 using namespace std;
     4 
     5 const int N = 1000000;
     6 int prime[N];
     7 
     8 void sieve()
     9 {
    10     int cnt = 0;
    11     memset( prime, -1, sizeof(prime) );
    12     prime[0] = prime[1] = cnt++;
    13     for ( int i = 2; i < N; i++ )
    14     {
    15         if ( prime[i] == -1 )
    16         {
    17             prime[i] = cnt++;
    18             for ( int j = i << 1; j < N; j += i )
    19             {
    20                 prime[j] = prime[i];
    21             }
    22         }
    23     }
    24 }
    25 
    26 int main()
    27 {
    28     sieve();
    29     int n;
    30     while ( scanf("%d", &n) != EOF )
    31     {
    32         printf("%d
    ", prime[n]);
    33     }
    34     return 0;
    35 }

    无论是空间时间还是代码总量都要优于第一个方法。

  • 相关阅读:
    oracel 备份导出报错 EXP-00091: Exporting questionable statistics
    将多张图片快速制作成一个PDF文件
    自连接表:M可能无下级,可能有下级
    STL迭代器失效总结
    DNS劫持和DNS污染的区别
    snprintf函数用法(转)
    sql查询面试题
    linux获取主机信息
    linux网络通信中的地址形式转换
    printf函数编程小技巧
  • 原文地址:https://www.cnblogs.com/huoxiayu/p/4445624.html
Copyright © 2020-2023  润新知