poj 2689(筛质数)

题目地址
可以通过 R-L来寻找突破口, 对于任何一个合数都有不超过sqrt(n)的因子,所以我们可以筛出2~sqrt®的质数再通过这些质数将L-R中的所有非质数标记。最后直接枚举。

对于筛选出来的每一个质数p,它对应L-R区间的倍数为j*p(ceil(L/p) <= j <= R/p)

详细见代码

#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
//#include<bits/stdc++.h>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#define int long long
#define sc scanf
#define pf printf
using namespace std;
typedef pair<int,int> pii;
typedef long long ll;
typedef unsigned long long LL;
 
const int INF = 0x3f3f3f3f;
const double eps = 1e-4;
const int mod = 1e9+7;
const int N = 1000010;

int primes[N],pos,l,r,cnt;
bool book[N],book1[N];

signed main(){
	IOS;
	#ifdef ddgo
		freopen("C:/Users/asus/Desktop/ddgoin.txt","r",stdin);
	#endif
	for(int i=2;i<=50000;i++)//筛质数,50000是根据题目的范围求得
		if(!book[i]){
			primes[cnt++] = i;
			for(int j=i;j*i<=50000;j++) book[i*j] = true;
		}
	while(cin>>l>>r){
		memset(book1,false,sizeof(book1));
		if(l == 1) book1[0] = true;//特判一下1
		for(int i=0;i<cnt&&primes[i]<r;i++){//根据质数将书友L-R的非质数标记
			int p = primes[i];
			for(int j=max(2ll,(l+p-1)/p);j<=r/p;j++) //这里j不能为1倍
				book1[p*j-l] = true;
		}
		
		int ma = -INF,mi = INF,x=-1;
		int mi_l=0,mi_r=0,ma_l=0,ma_r=0;//循环找出答案
		for(int i=0;i<=r-l;i++){
			if(book1[i]) continue;
			if(x == -1) x = i;
			else{
				if(i-x < mi){
				mi = i-x;
				mi_l = x+l;
				mi_r = i+l;
				}
				if(i-x > ma){
					ma = i-x;
					ma_l = x+l;
					ma_r = i+l;
				}
				x = i;
			}
		}
		if(ma == -INF || mi == INF) cout<<"There are no adjacent primes."<<endl;
		else cout<<mi_l<<","<<mi_r<<" are closest, "<<ma_l<<","<<ma_r<<" are most distant."<<endl;
	}
	
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值