机试算法讲解: 第25题 人人都爱素数筛选法

来源:互联网 发布:mac电脑怎么收藏网页 编辑:程序博客网 时间:2024/06/15 17:25
/*素数筛选法:若一个数不是素数,必定存在一个小于它的素数为其因数。假如已经获得了小于一个数的所有素数,只需确定该数不能被这些素数整除。在获得一个素数时,将它所有的倍数标记成非素数,当遍历到一个数时,它没有被任何小于它的素数标记为非素数时,就认为它是素数。输入:一个整数n,(2<=n<=10000),要求输出所有从1到这个整数之间(不包括1和这个整数)个位为1的素数,如果没有,则输出-1。输入:100输出:11 31 41 61 71素数之间用空格隔开,最后一个素数后面没有空格,如果没有则输出-1关键:1预处理2到1000000的所有素数2判定i为素数时,要标记其所有倍数为非素数,不从2*i标记,从i*i标记,因为i*k在求得k的素因数时被标记过,i*k同时也是k的素因数的倍数*/#include <stdio.h>#include <stdlib.h>int prime[10000];//保存素数int primeSize;//保存素数的个数bool mark[10001];//mark[x]=true表示该数x已经被标记成非素数void init(){int i ;for(i = 1 ; i <= 10000 ; i++ ){mark[i] = false;//默认为素数}primeSize = 0;//依次遍历2到10000的所有数字,若已经标记为非素数则跳过,否则,得到一个新素数for(i = 2; i <= 10000 ; i++){//如果是非素数,则跳过if(true==mark[i]){continue;}//素数则加1prime[primeSize++] = i;//易错,将该素数的倍数从i*i起开始,标记为非素数,为truefor(int j = i * i ; j <= 10000 ; j += i){mark[j] = true;}}}int main(int argc,char* argv[]){//易错,刚开始要初始化素数筛选法bool isFirst = true;init();int iNum;while(EOF!=scanf("%d",&iNum)){//遍历素数,就将末尾为1的数字输出for(int i = 0 ; i < primeSize ; i++){if(prime[i] < iNum && prime[i] % 10 ==1){if(isFirst){isFirst = false;printf("%d",prime[i]);}else{printf(" %d",prime[i]);}}}//如果没有符合要求的素数,直接打印-1if(isFirst==true){printf("%d",-1);}}system("pause");getchar();return 0;}

0 0