• 素数多写法


    题目推荐:http://ybt.ssoier.cn:8088/problem_show.php?pid=1151

        https://www.luogu.com.cn/problem/P3383

    第二个题数据规模有点儿doge,所以建议直接用欧拉筛来提交

    第一种写法:朴素筛

    1.O(n^2)写法

    using namespace std;
    //询问一个数,输出一行Yes或No。 
    int n;
    bool pd=1; 
    int main()
    {
           scanf("%d",&n);
           if(n==1)printf("No");//特判。
           for(int i=2;i<n;i++)//枚举到n前一个。
           {
            if(n%i==0)
            {
                pd=0;
                break;
            }
        }
        if(pd)printf("Yes");
        else printf("No");
        return 0;
        QWQ;
    }

    稍稍给它优化优化,枚举到√n;

    2.O(n*√n)写法:

    using namespace std;
    //询问一个数,输出一行Yes或No。 
    int n; 
    bool pd=1; 
    int main()
    {
           scanf("%d",&n);
           if(n==1)printf("No");//特判。
           for(int i=2;i*i<=n;i++)//这次枚举到根号n,因为根号n到n之间的数都不是n的因数
           {
            if(n%i==0)
            {
                pd=0;
                break;
            }
        }
        if(pd)printf("Yes");
        else printf("No");
        return 0;
        QWQ;
    }

    但是这样按照此题要判断多次,时间复杂度肯定很高是不行滴 试过

    接下来再介绍两种高效率区间筛:

    二:埃氏筛

    当需要求某一区间[2,n]内的所有素数时,可以从2开始,对于当前素数p,将p^2p2后所有p的倍数筛去每次找到下一个没有被筛到的数就是一个素数。

    #include<bits/stdc++.h>
    using namespace std;
    int a[100005],n,q,x;
    bool ss(int x)
    {
        bool f=1;
        for(int i=2;i<=sqrt(x);i++)
        {
            if(x%i==0)
            {
                f=0;
                break;      
            }    
        }    
        return f;
    } 
    int main(){
        cin>>n>>q;
        int sum=1;
        for(int i=2;i<=n;i++){
            if(ss(i)){
                a[sum]=i;
                sum++;
            }
        }
        while(q--){
            cin>>x;
            cout<<a[x]<<endl;
        }
        return 0;
    }

    当然,这种算法并不完美,因为有些合数会被筛两次。

    比如6,会被2筛一次,3一次,为了优化,我们用出了另一种更高效率的区间筛

    所以:

    三:欧拉筛

    欧拉筛法的基本思想 :在埃氏筛法的基础上,让每个合数只被它的最小质因子筛选一次,以达到不重复的目的。

    具体详解,请见:https://blog.csdn.net/qq_39763472/article/details/82428602

    #include<bits/stdc++.h>
    using namespace std;
    int sum=1,n,m,x,a[100000001];
    bool un[100000001];
    
    void oula(int x){
        for(int i=2;i<=n;i++){
            if(un[i]==false){
                a[sum++]=i;
            }
            for(int j=1;j<=sum && i*a[j]<=n;j++){
                un[i*a[j]]=true;
                if(i%a[j]==0) break;
            }
        }
    } 
    
    int main(){
        cin>>n>>m;
        oula(n);
        while(m--){
            cin>>x;
            cout<<a[x]<<endl;
        }
        return 0;
    }

    最后,奉上推荐题的AC代码,方便各位复制粘贴

    1.

    #include<iostream>
    #include<cmath>
    using namespace std;
    bool judge(int x)
    {
        bool f=1;
        for(int i=2;i<=sqrt(x);i++)
        {
            if(x%i==0)
            {
                f=0;
                break;      
            }    
        }    
        return f;
    } 
    int main()
    {
        int n;
        int sum=0;
        cin>>n;
        for(int i=2;i<=n;i++)
        {
            if(judge(i))
            {
                sum++;
            }
        }
        cout<<sum<<endl;;
        return 0;
    }

    2.

    #include<bits/stdc++.h>
    using namespace std;
    int sum=1,n,m,x,a[100000001];
    bool un[100000001];
    
    void oula(int x){
        for(int i=2;i<=n;i++){
            if(un[i]==false){
                a[sum++]=i;
            }
            for(int j=1;j<=sum && i*a[j]<=n;j++){
                un[i*a[j]]=true;
                if(i%a[j]==0) break;
            }
        }
    } 
    
    int main(){
        cin>>n>>m;
        oula(n);
        while(m--){
            cin>>x;
            cout<<a[x]<<endl;
        }
        return 0;
    }

     

  • 相关阅读:
    面向对象进阶----->反射 getattr 和hasattr方法
    封装和 property方法
    C/S与B/S区别
    BIO、NIO和AIO
    ArrayList、Vector、LinkedList的区别
    AOP代理模式
    Anonymous Inner Class (匿名内部类) 是否可以extends(继承)其它类,是否可以implements(实 现)interface(接口
    Spring常见面试题及答案解析
    数据库优化
    事物的理解
  • 原文地址:https://www.cnblogs.com/qwn34/p/15160676.html
Copyright © 2020-2023  润新知