1013 数素数 (20)(20 分)
作者: CHEN, Yue
单位: PAT联盟
时间限制: 200ms
内存限制: 64MB
代码长度限制: 16KB
令P~i~表示第i个素数。现任给两个正整数M <= N <= 10^4^,请输出P~M~到P~N~的所有素数。
输入格式:
输入在一行中给出M和N,其间以空格分隔。
输出格式:
输出从P~M~到P~N~的所有素数,每10个数字占1行,其间以空格分隔,但行末不得有多余空格。
输入样例:
5 27
输出样例:
11 13 17 19 23 29 31 37 41 43
47 53 59 61 67 71 73 79 83 89
97 101 103
这道题很简单,我想到了两个思路:
1.暴力求解,使用判断函数一个一个判断,直到找到需要的素数个数
2.使用埃式筛法,边筛选边输出
还有存在一个问题就是素数个数上限在10的四次方,但是不知道具体第10000个素数的大小是多大,这时《算法笔记》中建议把上限设尽量大一点。
事实上我在做这道题的时候也简单的进行了一个估算,10以内有4个素数,100个以内有至少10个素数,那么按照这样下去,范围与素数个数应该是差一个数量级的关系,实际的结果我也搜索了一下,可以简单的记忆一下说不定有用:
10 以内共 4 个质数.
100 以内共 25 个质数.
1000 以内共 168 个质数.
10000 以内共 1229 个质数.
100000 以内共 9592 个质数.
1000000 以内共 78498 个质数.
10000000 以内共 664579 个质数.
100000000 以内共 5761455 个质数.
当然这只是网上的搜索结果,正确性还有待确认。
所以这道题在我的估算下 我试用了10的5次方乘2的范围来作为寻找素数的范围,这样是没有问题的。
AC代码:
#include <cstdio>
int main() {
const int maxn = 200000;
int m, n, pNum = 0, priNum = 1;
bool p[maxn] = {0};
scanf("%d%d", &m, &n);
for(int i = 2; pNum < n; ++i) {
if(!p[i]) {
for(int j = i + i; j < maxn; j += i) {
p[j] = true;
}
++pNum;
if(pNum >= m) {
if(priNum == 10 || pNum == n) {
printf("%d\n", i);
priNum = 1;
} else {
printf("%d ", i);
++priNum;
}
}
}
}
return 0;
}
如有错误,欢迎指摘。