CodeForces - 237C Primes on Interval(二分+尺取)
You've decided to carry out a survey in the theory of prime numbers. Let us remind you that a prime number is a positive integer that has exactly two distinct positive integer divisors.
Consider positive integers a, a + 1, ..., b (a ≤ b). You want to find the minimum integer l (1 ≤ l ≤ b - a + 1) such that for any integer x (a ≤ x ≤ b - l + 1) among l integers x, x + 1, ..., x + l - 1 there are at least k prime numbers.
Find and print the required minimum l. If no value l meets the described limitations, print -1.
Input
A single line contains three space-separated integers a, b, k (1 ≤ a, b, k ≤ 106; a ≤ b).
Output
In a single line print a single integer — the required minimum l. If there's no solution, print -1.
Example
Input
2 4 2
Output
3
Input
6 13 1
Output
4
Input
1 4 3
Output
-1
题意:找到最小的l,使[a,b]中所有长度为l的区间都能找到k个素数,如果找不到,输出"-1"
分析: 答案是线性相关的,所以我们可以二分答案,然后再通过尺取法判断该长度是否满足条件
代码如下:
#include<iostream> #include<cstring> #include<cstdio> using namespace std; const int MAXN=2e6+10; int a,b,k; int flag[MAXN]; int flag2; int que[MAXN]; bool check(int len) { // puts("c"); int num,len1,l,r,now; int flag3; flag3=1; l=0,r=0; now=0; while(1) { while(r-l<len) { que[r++]=a+r-1; if(flag[a+r-1]){ now++; } if(a+r-1==b)break; } if(r-l==len) { if(now<k) flag3=0; // cout<<" "<<que[l]<<endl; if(flag[que[l]]){ now--; } l++; } if(flag3==0||a+r-1==b) break; } if(flag3==1)return true; return false; } int main() { flag[1]=0; flag[2]=1; for(int i=3;i<=1000100;i++) { flag2=1; for(int j=2;j*j<=i;j++) { if(i%j==0) { flag2=0; break; } } flag[i]=flag2; } while(scanf("%d%d%d",&a,&b,&k)!=EOF) { int l,r,mid; l=0; r=b-a+1; while(l+1<r) { mid=(l+r)/2; if(check(mid)) r=mid; else l=mid; } if(check(r))printf("%d\n",r); else puts("-1"); } return 0; }