筛法求素数

来源:互联网 发布:js 模拟dos 编辑:程序博客网 时间:2024/06/07 01:18

问题描述

Problem B: 筛法求素数

Time Limit: 1 Sec  Memory Limit: 128 MB
Submit: 138  Solved: 67
[Submit][Status][Web Board]

Description

用筛法求之N内的素数。

Input

N

Output

0~N的素数

Sample Input

100

Sample Output

2357111317192329313741434753596167717379838997

HINT

数组大小动态定义?函数?

解题思路

想像将100个数看作沙子和小石头,让小石头子充当素数,让沙子当作非素数。弄一个筛子,只要将沙子筛走,剩下的就是素数了。非素数一定是2,3,4等的倍数。使用数组,让下标就是100以内的数,让数组元素的值作为筛法与否的标志,比如筛去以后让元素值为1,见下面的图

图 筛法思路:让数组元素值作为筛去的标志

让数组元素值作为筛去的标志

方法依据

1至100这些自然数可以分为3类。

(1)单位数:仅有一个数1。

(2)素数:是这样一个数,它大于1,且只有1和它本身这样两个正因数。

(3)合数:除了1和自身以外,还有其他正因数。

筛法实际上筛去合数,留下素数。为了提高筛法效率,注意到:

如 n 为合数(这里是100),c 为 n 的最小正因数,则有

1 <= c <= sqrt(n)

据初等数论,只要找到 c 就可以确认 n 为合数,将其筛去。

(1)第一块是一个计数型的循环语句,功能是将prime数组置零,prime[c] = 0;c = 2,3,4,~~~,100。

(2)第二块是让正因数 d 初始化为 d = 2。

(3)第三块是循环筛数。

图 筛法求素数的程序框图

筛法求素数的程序框图

代码

#include <iostream>#include <cmath>using namespace std;int array[10000] = {0};int main(){int N;cin >> N;int d = 2;int k;do {k = d;if (array[k] == 0){k += d;while (k <= N){array[k] = 1;k += d;}}++d;} while (d <= sqrt(N));int i;for (i = 2; i <= N; ++i){if (array[i] == 0)cout << i << endl; }return 0;}


原创粉丝点击