1.21素数区间

★实验任务
dark di 在做数学题目的时候发现了一个现象,2 个相邻的素数之间存在一个区间,他把这个区间称为非素数区间,那么 darkdi 想知道,给定一个正整数x,x 所在的非素数区间长度是多少呢?
例如 23 和 29 是 2 个相邻的素数,他们之间的非素数区间是[24,28],长度是 5,假设 x=27,那么 x 所在的非素数区间长度就是 5。如果 x 是一个素数,则答案是 0。
注意:素数指的是除了 1 和它本身以外不再有其他因数的自然数。
★数据输入
第一行输入一个正整数 T,表示接下去有 T 次询问。
接下去 T 行,每行一个正整数 x。(2<=x<=100000)。
对于 30%的数据,T<=5,2<=x<=100
对于 80%的数据,T<=10,2<=x<=5000
对于 100%的数据,T<=100000,2<=x<=100000
★数据输出
输出 T 行,每行一个整数表示非素数区间的长度。
★输入示例
1
27
输出示例
5

解题思路:
先用欧拉筛选法找出所有素数,然后采用二分法找到x所在区间。
解题代码:

#include <bits/stdc++.h>
using namespace std;
#define MAXN 100001
bool isprime[MAXN];
int prime[MAXN];
int cnt;
void euler()
{
    memset(isprime, true, sizeof(isprime));
    isprime[1] = false;
    for(int i=2;i<=MAXN;i++)
    {
        if(isprime[i])
        {
            cnt++;
            prime[cnt]=i;
        }
        for(int j=1;j<=cnt&&i*prime[j]<=MAXN;j++)
        {
            isprime[i*prime[j]]=false;
            if(i%prime[j]==0)
            break;
        }
    }
}
int main()
{
    int t, x;
    euler();
    cin>>t;
    for(int i=0;i<t;i++)
    {
        cin>>x;
        if(x==0||x==1||isprime[x])
        {
            cout<<'0'<<endl;
            continue;
        }
        int l=1,r=cnt,mid,ans;
        while(l<=r)
        {
            mid=(l+r)>>1;
            if(x>prime[mid])
            {
                ans=mid;
                l=mid+1;
            }
            else if(x<prime[mid])
            {
                r=mid-1;
            }
        }
        cout<<prime[ans+1]-prime[ans]-1<<endl;
    }
    return 0;
}
mid=(L+R)>>1;  //该行代码等同于mid=(L+R)/2
posted @ 2022-09-13 20:36  Linkway  阅读(62)  评论(0)    收藏  举报