1 solutions
-
0
这道题算是一个比较综合的问题了,不仅需要用素数筛找出素数,还要用二分法找出对应的区间,在二分的过程中,可以将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; }
Information
- ID
- 1542
- Time
- 1000ms
- Memory
- 256MiB
- Difficulty
- 7
- Tags
- # Submissions
- 116
- Accepted
- 26
- Uploaded By