时间限制:3.000秒
数学题,多组测试数据,每组一个整数n(n ≤ 1299709,即第100000个素数),求大于等于该数的最小素数和小于等于该数的最大素数的差。例如,n == 27时输出6(29 - 23 = 6),n为素数时结果为0。
我的算法是先用筛法筛出素数表p来,然后根据素数表再打两个表l和u,其中l[i]代表小于等于i的最大素数,u[i]代表大于等于i的最小素数。
有关筛法:
素数是仅能被1和自身整除的整数,最简单的方法就是从2到n-1(优化的话是2到√(n))判断能否被整除,但是这样效率很低,因为需要大量的重复运算。所以一般用筛法打素数表。筛法的思想就是对于不超过n的每个非负整数p,依次删除2p,3p,4p,……,这样处理完所有数之后,还没有被删除的数就是素数。刘汝佳《算法竞赛入门经典(第二版)》上给出了优化过的筛法的代码,如下:
//处理之后vis[i]即表示i是否为素数,1代表不是,0代表是。
int m = sqrt(n + 0.5);
memset(vis, 0, sizeof(vis));
for(int i = 2; i <= m; i++) if(!vis[i]) for(int j = i * i; j <= n; j += i) vis[j] = 1;
代码:
#include
#include
#include
using namespace std;
int p[1300000];
int l[1300000];
int u[1300000];
int main() {
int m = sqrt(1300000 + 0.5) + 1;
for(int i = 2; i != 1300000; ++i) p[i] = 1;
for(int i = 2; i != m; ++i) if(p[i]) for(int j = i * i; j < 1300000; j += i) p[j] = 0;
for(int i = 1; i != 1300000; ++i) {
if(p[i]) l[i] = i;
else l[i] = l[i - 1];
}
for(int i = 1299999; i >= 0; --i) {
if(p[i]) u[i] = i;
else u[i] = u[i + 1];
}
int n;
while(cin >> n && n) cout << u[n] - l[n] << endl;
return 0;
}