素数筛选

素数:又称质数(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的素因数的时候标记了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值