素数筛选

来源:互联网 发布:铜牌在线制作软件 编辑:程序博客网 时间:2024/06/06 04:56

素数:又称质数(prime number),有无限个。
质数定义为在大于1的自然数中,除了1和它本身以外不再有其他因数的数称为质数。
判断一个数n是否为素数:从2开始到sqrt(n)是否有可以整除n的数,若存在,则不为素数;否则为素数。
时间复杂度:O(sqrt(n))

题目1047:素数判定时间限制:1 秒内存限制:32 兆特殊判题:否提交:14099解决:6378题目描述:给定一个数n,要求判断其是否为素数(0,1,负数都是非素数)。输入:测试数据有多组,每组输入一个数n。输出:对于每组输入,若是素数则输出yes,否则输入no。样例输入:13样例输出:yes
#include <iostream>#include<math.h>/* run this program using the console pauser or add your own getch, system("pause") or input loop */using namespace std;int n;bool isPrime(int n){    bool ans=true;    int bound=sqrt(n);    for(int i=2;i<=bound;i++){        if(n%i == 0){            ans=false;            break;        }    }    return ans;}int main(int argc, char *argv[]) {    while(cin>>n){        if(n>1 && isPrime(n) == true){            cout<<"yes"<<endl;        }else{            cout<<"no"<<endl;        }    }    return 0;}

素数筛选法:
原理:若一个数不是素数,则必存在一个小于它的素数因子。
当获得一个素数时,即将它所有的倍数进行标记为非素数。
当一个数没有被标记,则表明其为素数。
可能存在一个数没有被标记但是是非素数吗?
假设存在一个非素数N,它没有被标记,即N不存在一个比它小的素数因子,也就是N除了1和N以外没有能够整除N的数,那么N就是个素数,与假设矛盾。因此,不可能存在一个数没有被标记却是非素数。

题目1163:素数时间限制:1 秒内存限制:32 兆特殊判题:否提交:13205解决:4627题目描述:输入一个整数n(2<=n<=10000),要求输出所有从1到这个整数之间(不包括1和这个整数)个位为1的素数,如果没有则输出-1。输入:输入有多组数据。每组一行,输入n。输出:输出所有从1到这个整数之间(不包括1和这个整数)个位为1的素数(素数之间用空格隔开,最后一个素数后面没有空格),如果没有则输出-1。样例输入:100样例输出:11 31 41 61 71来源:2008年北京航空航天大学计算机研究生机试真题

代码:

#include <iostream>#define N 10001  //筛选出2-10000之间的所有素数using namespace std; /*     输入一个整数n(2<=n<=10000),    要求输出所有从1到这个整数之间(不包括1和这个整数)个位为1的素数,    如果没有则输出-1。*/int prime[N];  //保持筛选出的素数int primelength=0;   //记录筛选出的素数的个数int mark[N];void findPrime(){    //素数筛选    //1.初始化所有数字都没有被标记     for(int i=0;i<N;i++){        mark[i]=false;    }     //2.开始筛选     for(int i=2;i<N;i++){        if(mark[i] == true){            continue;  //该数已经标记了         }        mark[i]=true;  //否则就标记该数        prime[primelength++]=i;         //cout<<i<<endl;        for(int j=i*i;j<N;j+=i){  //标记i的倍数            mark[j]=true;        }     }} int main(int argc, char *argv[]) {    //1.预处理筛选出素数    findPrime();      //2.从筛选出的素数选择出符合条件的素数     int n;    while(cin>>n){        bool exits=false;  //标记是否有满足条件的素数         for(int i=0;i<primelength;i++){            if(prime[i] < n ){                if(prime[i]%10 == 1){                    if(exits == false){ //第一个素数                         cout<<prime[i];                    }else{                         cout<<" ";                         cout<<prime[i];                    }                    exits=true;                }            }else{  //素数已经大于n,则停止                 break;            }         }        if(exits == false){            cout<<"-1";        }        cout<<endl;    }     return 0;}

其中素数筛选的模板为:

#include <iostream>#define N 10001  //筛选出2-10000之间的所有素数using namespace std; /*     输入一个整数n(2<=n<=10000),    要求输出所有从1到这个整数之间(不包括1和这个整数)个位为1的素数,    如果没有则输出-1。*/int prime[N];  //保持筛选出的素数int primelength=0;   //记录筛选出的素数的个数int mark[N];void findPrime(){    //素数筛选    //1.初始化所有数字都没有被标记     for(int i=0;i<N;i++){        prime[i]=false;    }     //2.开始筛选     for(int i=2;i<N;i++){        if(mark[i] == true){            continue;  //该数已经标记了         }        mark[i]=true;  //否则就标记该数        prime[primelength++]=i;         //cout<<i<<endl;        for(int j=i*i;j<N;j+=i){  //标记i的倍数            mark[j]=true;        }     }} 

其中判定i为素数时,标记从i*i开始而不是2*i的原因是
k * i( k < i ) 的数已经在求得k的素因数的时候标记了。

0 0
原创粉丝点击