zoukankan      html  css  js  c++  java
  • SCAU 8614 素数

    8614 素数

    时间限制:500MS  内存限制:1000K 提交次数:0 通过次数:0

    题型: 编程题   语言: 无限制

    Description

    数学对于计算机学是很重要的,大一的高数就曾经(或即将)令一批又一批人饮恨。这里就是一个数学问题,当然,它不需要用到高深的高数知识。
    给出n(1<=n<=100000),问1到n之间有几个素数。 

    Input

    第1行,1个整数T(T<=100000),表示共有T组测试数据
    第2---第T+1行,每行1个整数,表示测试数据n 

    Output

    对于每个测试数据,输出1行,每行1个数,表示1到n之间的素数个数

    Sample Input

    5
    1
    2
    100
    1000
    5000
    
    

    Sample Output

    0
    1
    25
    168
    669
    

    Source

    白衣人

    Provider

    admin

     

    #include <stdio.h>
    #include <string.h>
    int prime[100001];
    int cnt[100001];
    int main()
    {
        int i,j,t;
        memset(prime,0,sizeof(prime));
        memset(cnt,0,sizeof(cnt));
        prime[0]=prime[1]=1;
        for(i=2;i<100000;i++)
        if(prime[i]==0){
        for(j=i+i;j<100001;j+=i)
        prime[j]=1;
        }
        int ans=0;
        for(i=2;i<100001;i++){
        if(!prime[i]) 
        ans++;
        cnt[i]=ans;
        }
        scanf("%d",&t);
        while(t--){
            int n;
            scanf("%d",&n);
            printf("%d\n",cnt[n]);
        }
    }

    解题报告:
    因为对我来说是一种打击,不断地超时,一直认为是筛素数出现了问题,而不会去考虑最大的复杂度是多少。印象深刻,我想思维可以有无限的区域,为何要苦苦局限于一点,这点让我知道了自己的不足,也让我坚定了做题的决心,就是为了要锻炼和改变一下逻辑思维能力,这题能学到什么,完全是因人而异的。

    下面是另外两种筛素数的方法,仅作参考

    Is_prime Code
    #include<stdio.h>
    #include<string.h>
    #include<time.h>
    #define MAXN 10000000
    int prime[MAXN]; 
    int flag[MAXN];
    int main()
    {
        int i, j, n, m = MAXN, count = 0;
        clock_t start, end;
        start = clock(); 
        memset(prime, 0, sizeof(prime));   //筛素数一 
        prime[0]=prime[1]=1;
        for(i=2;i<MAXN;i++)
        if(!prime[i]){
        for(j=i+i;j<MAXN;j+=i)
        prime[j]=1;    
        }
        end = clock();
        printf("MAXN = %d时 素数筛选法一所用时间:time = %dms\n", m, end-start);
        
       //以下标作为素数,跟下面判断存储素数的方法不同 
    
        start = clock(); 
        n = 0;
        memset(flag, 0, sizeof(flag));
        memset(prime, 0, sizeof(prime));
        for(i=2; i<MAXN; i++)
        {
            if(!flag[i])   
            {
                prime[n++] = i;
                for(j=i+i; j<MAXN; j+=i)
                flag[j] = 1;
            } 
        }
        end = clock();
        printf("MAXN = %d时 素数筛选法二所用时间:time = %dms\n",m, end-start);
        
        //这里还有可以改进的地方,将j=i+i 换成 j=i*i。但要注意整数溢出! PS对于一个数x,假设它含有质因子i,那么令y=x/i;可以发现,
        //如果所有小于i*i的含有因子i的数字,其y值小于i,这样的话,在以前的筛选过程中,就会把x筛掉
        
        start = clock(); 
        n = 0;
        memset(flag, 0, sizeof(flag));
        memset(prime, 0, sizeof(prime));
        for(i=2; i<MAXN; i++)
        {
            if(!flag[i]) prime[n++] = i;   
            for(j=0; j<n&&prime[j]*i<MAXN; ++j)
            {
                flag[prime[j]*i] = 1;
                if(!(i%prime[j])) break;
            } 
        }
        end = clock();
        printf("MAXN = %d时 素数筛选法三所用时间:time = %dms\n",m, end-start);
        
        //i = 2 flag[2]==0 2是素数,所以存进prime[0] n=1, 在下面的for循环中 flag[2*2=4] = 1;2%2 == 0 break;
        //i = 3 flag[3]==0 3是素数, 存进prime[1] n=2; for循环中: flag[3*2=6] = 1, flag[3*3=9] = 1, 3%3 == 0 break;
        //i = 4 flag[4]==1 4不是素数 n=2;for循环中: flag[4*2 = 8] = 1; 4%2 == 0 break; 
        //说明break的作用:先看看不break会发生什么情况, flag[4*3=12] = 1; 而你也会发现循环到i=6时flag[6*2=12]将会再一次赋值为1 
        //要这样做的原因是想到:每个非素数都有一个最小素因子,而我们的目的是想最优化,必然要除去重复计算的情况,所以根据非素数的
        // 最小素因子判定该非素数(合数)就能除去重复计算的情况, 而代码中,i%prime[j] == 0 时,此时的prime[j]是最小素数,而i可以
        //判定是一个合数,没break这个条件再往下乘的话,那么j里面肯定带有一个相乘后得到的这个数((i*prime[j+1])的最小素因子,而这个
        //可以在另外一种情况prime[`i] = 该最小素因子中判定。比如说flag[6*3 = 18] 和 flag[9*2] = 18, 带break条件就会将flag[6*3 = 18]
        //这种情况忽略, 因为在这之前6%2 == 0。 
        return 0;
    } 

    输出情况如下:

          哪一种方法较为优化一目了然

  • 相关阅读:
    Windows:C:WindowsSystem32driversetchosts
    Quartz:Cron Expressions
    RabbitMQ:基本命令
    架构:一致性
    Javascript:自己写异步流程编程框架
    Python:Hello World级别的SimpleDb
    架构:互联网架构
    数据访问:三大范式
    数据访问:Implementing Efficient Transactions
    技术人生:special considerations that are very important
  • 原文地址:https://www.cnblogs.com/liaoguifa/p/2767223.html
Copyright © 2011-2022 走看看