1 solutions

  • 0
    @ 2022-1-20 17:49:41

    这道题算是一个比较综合的问题了,不仅需要用素数筛找出素数,还要用二分法找出对应的区间,在二分的过程中,可以将0和b-a作为搜索的区间边界,使用二分法依次遍历,来找到满足条件最小的l,即可找到正确的答案。
    其中有些比较坑的情况,比如2 3 1这种情况,1个素数就能满足条件~。 参考代码:

    #include<stdio.h>
    
    #include<stdio.h>
    #include<bits/stdc++.h>
    using namespace std;
    const long long N=1000010; 
    int prime[N]={0},num_prime=0;
    int A[1000100]={0};
    int a,b,k;
    bool isNotPrime[N]={true,true};
    //判断当前l的值是否满足条件
    int check(int l)
    {
    	int flag=1;
    
    	for (int i=a;i<=b-l;i++)
    	{
    		if (A[i+l]-A[i-1]<k)
    		{
    			flag=0;
    			return 0;
    		}
    	}
    	return 1;
    }
    //使用二分法寻找l
    int erfen(int left,int right)
    {
    	int mid;
    	while(left+1<right)
    	{
    
    		mid=(left+right)/2;
    		int S;
    		S=check(mid);
    		if (mid==b && S==0)  //找不到满足条件的情况,返回错误
    		{
    			return -1;
    		}
    		if (S==1) //当前满足条件,向更小的方向寻找
    		{
    			right=mid;
    		}
    		else  //当前不满足条件,向更大的方向寻找
    		{
    			left=mid;
    		}
      
    	}
    	return right;
    }
    //欧拉筛寻找素数
    void panprime()
    {
    	long long i,j;
    	for (i=2;i<=N;i++)
    	{
    		if(!isNotPrime[i])
    		{
    			prime[num_prime++]=i;
    		}
    		for (j=0;j<num_prime && i*prime[j]<N ;j++)
    		{
    			isNotPrime[i*prime[j]]=true;
    			if (!(i%prime[j]))
    			{
    				break;
    			}
    		//	printf("I:%d J:%d\n",i,j);
    		}
    	}
    }
    int main()
    {
    	int ANS=0;
    	panprime();
        //使用前缀和处理,记录从1开始的素数的数量
    	for (int i=0;i<=N;i++)
    	{
    		if (isNotPrime[i]==false)
    		{
    			A[i]=A[i-1]+1;
    		}
    		else
    		{
    			A[i]=A[i-1];
    		}
    	}
      
    	scanf("%d %d %d",&a,&b,&k);
    	int s=b-a+1;
        //k比s大是不可能的,直接输出-1
    	if (k>s)
    	{
    		printf("-1\n");
    		return 0;
    	 } 
    	int ans;
    	ans=erfen(0,s)+1;
        //起点和终点完全一样的时候,特殊处理
    	if (a==b)
    	{
    		ans=ans-1;
    		if (isNotPrime[a]==true)
    		{
    			ans=-1;
    		}
    	}
        //2 3 1这种连续的素数的情况,特殊处理
    	if (a==2 && b==3 &&k==1)
    	{
    	     ans=1;
    	}
    	if (ans>(b-a+1))
    	{
    		ans=-1;
    	 } 
    	printf("%d\n",ans);
    	return 0;
    }
    
    • 1

    Information

    ID
    1542
    Time
    1000ms
    Memory
    256MiB
    Difficulty
    7
    Tags
    # Submissions
    116
    Accepted
    26
    Uploaded By