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
题目描述
给定两个整数 ,求闭区间 [ L , R ] [L,R] [L,R]中相邻两个质数差值最小的数对与差值最大的数对。当存在多个时,输出靠前的素数对。
输入格式
多组数据。每行两个数 L , R L,R L,R。
输出格式
详见输出样例。
样例
样例输入
2 17
14 17
样例输出
2,3 are closest, 7,11 are most distant.
There are no adjacent primes.
这一道题很明显是素数筛的题,一般做素数筛都用线筛,因为要快一些,这道题也一样。
直接每一次用线筛,筛出在 [ L , R ] [L,R] [L,R]这个区间的所有质数,然后再进行枚举比较求出间隔最小与间隔最大的相邻质数。
#include
#include
#include
#include
using namespace std;
const int M = 1e8 + 5;
bool flag[M];
int pre[M];
int prime(int l, int r) {
memset(flag, false, sizeof(flag));
memset(pre, 0, sizeof(pre));
int k = 0;
if (l == 1) {
l++;
}
for (int i = 2; i <= r; i++) {
if (!flag[i]) {
k++;
pre[k] = i;
}
for (int j = 1; j <= k && pre[j] * i <= r; j++) {
flag[pre[j] * i] = true;
if (i % pre[j] == 0)
break;
}
}
return k;
// for(int i=1;i<=k;i++){
// printf("%d ",pre[i]);
// }
}
int main() {
int L, R;
while (scanf("%d %d", &L, &R) != EOF) {
int len = prime(L, R);
if (len == 1) {
printf("There are no adjacent primes.\n");
}
int x1 = 0, x2 = 0, y1 = 0, y2 = 0;
int minn = 0x3f3f3f3f, maxn = 0;
for (int i = 1; i <= len - 1; i++) {
if (pre[i + 1] - pre[i] < minn && pre[i] >= L) {
x1 = i, x2 = i + 1;
minn = pre[i + 1] - pre[i];
}
if (pre[i + 1] - pre[i] > maxn && pre[i] >= L) {
y1 = i, y2 = i + 1;
maxn = pre[i + 1] - pre[i];
}
}
if (x1 == 0 && x2 == 0 && y1 == 0 && y2 == 0) {
printf("There are no adjacent primes.\n");
continue;
}
printf("%d,%d are closest, %d,%d are most distant.\n", pre[x1], pre[x2], pre[y1], pre[y2]);
}
return 0;
}
但是一提交就直接超时爆零了。
之后我就反思为何会超时。首先,主函数里遍历答案这是不可去除的;之后就是线筛函数也不会错。最后,我发现在每次输入 L , R L,R L,R之后,都有一次线筛,那万一第一个数据都包含了之后的数据,就不是浪费时间了。
所以我们可以找到数据的极值,即 M M M。在每次输入数据之前都进行一次最大的线筛,则后面的数据就直接使用就可以了。
#include
#include
#include
using namespace std;
const int M=1e7+5;
bool flag[M],flag1[M];
int pre[M],arr[M];
int k;
void Prime2(){
flag[0]=flag[1]=true;
for(int i=2;i<=M;i++){
if(flag[i]==false){
pre[k++]=i;
}
for(int j=1;j<k&&pre[j]*i<M;j++){
flag[pre[j]*i]=true;
}
}
}
int main(){
int L,R;
Prime2();
while(scanf("%d %d",&L,&R)!=EOF){
if(L==1){
L=2;
}
memset(flag1,false,sizeof(flag1));
for(int i=0;i<k;i++){
int a=(L-1)/pre[i]+1;
int b=R/pre[i];
for(int j=a;j<=b;j++){
if(j>1){
flag1[pre[i]*j-L]=true;
}
}
}
int x1=0,x2=0,y1=0,y2=0;
int minn=0x3f3f3f3f,maxn=-1,p=-1;
for(int i=0;i<=R-L;i++){
if(flag1[i]==false){
if(p==-1){
p=i;
continue;
}
if(i-p<minn){
x1=p+L,x2=i+L;
minn=i-p;
}
if(i-p>maxn){
y1=p+L,y2=i+L;
maxn=i-p;
}
p=i;
}
}
if(maxn==-1){
printf("There are no adjacent primes.\n");
continue;
}
printf("%d,%d are closest, %d,%d are most distant.\n",x1,x2,y1,y2);
}
return 0;
}