POJ 2689 Prime Distance 素数线性筛选

题目大意

给定左右区间,求出区间内两个相邻质数中相差最大和最小的两队, 没有就输出
There are no adjacent primes.

范围
1 ≤ L < R ≤ 2^31−1

样例

输入样例:
2 17
14 17
输出样例:
2,3 are closest, 7,11 are most distant.
There are no adjacent primes.

思路
        这里采用的是素数线性筛选, 但是因为数据范围不大,用朴素筛选也行, 具体的素数筛选讲解可以查看 ==>> 这篇博客
        L,R的范围很大,任何已知算法都无法在规定时间内生成[1,R] 中的所有质数。但是R-L的值很小,并且任何一个合数n必定包含一个不超过 √n的质因子。(关键)
        所以,我们只需要用筛法求出2 ~ sqrt( R )之间的所有质数。对于每个质数p,把[L,R]中能被p整除的数标记,即标记i * p( l / p ≤ i ≤ r / p)(上取整)为合数。
        最终所有未被标记的数就是[L, R]中的质数。对相邻的质数两两比较,找出差最大的即可。
        在存L 到 R 之间的素数时, 只需要存 P - L 就行了, 因为不能开那么大的空间, R - L 不大于1e6 所以开 1e6 + 10 的空间就够了

		for(int i = 1; i <= m; i++){
			int p = prime[i];
			 for (long long j = max((l + p - 1) / p * p, 2ll * p); j <= r; j += p)
                vis[j - l] = true;	//这里是j - l 不是存的j 
		}

        然后这里还原

		for(int i = 0; i <= r - l ; i++)
			 if(!vis[i]  && i + l > 1 )
			 	prime[++m] = i + l;

代码

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
using namespace std;
typedef long long ll; 
const int  N = 1000010;
int prime[N];
bool vis[N];
int m;
void get_primes(int n){
	memset(vis, false, sizeof vis);
	m = 0;
	for(int i = 2; i <= n; i++){
		if(!vis[i]) prime[++m] = i;
		for(int j = 1; prime[j] * i <= n; j++){
			vis[prime[j] * i] = true;
			if(i % prime[j] == 0) break;
		}
	}
}
int main(){
	ll l, r;
	
	while(~scanf("%lld%lld", &l, &r)){
		get_primes(50000);
		memset(vis, false, sizeof vis);
		for(int i = 1; i <= m; i++){
			int p = prime[i];
			 for (long long j = max((l + p - 1) / p * p, 2ll * p); j <= r; j += p)
                vis[j - l] = true;
			
		}
		m = 0;
		for(int i = 0; i <= r - l ; i++)
			 if(!vis[i]  && i + l > 1 )
			 	prime[++m] = i + l;
		if(m < 2) cout << "There are no adjacent primes." << endl;
		else{
			int minn = 1, maxx = 1;
			for(int i = 1; i <= m - 1; i++){
				int dis = prime[i + 1] - prime[i];
				if(dis < prime[minn + 1] - prime[minn]) minn = i;
				if(dis > prime[maxx + 1] - prime[maxx]) maxx = i;
			}	printf("%d,%d are closest, %d,%d are most distant.\n", prime[minn], prime[minn + 1], prime[maxx], prime[maxx + 1]);
		
			}
		
	}
	return 0;
} 
发布了54 篇原创文章 · 获赞 155 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qq_45432665/article/details/104144023
今日推荐