zcmu 1022 Primes on Interval(線性篩+二分)
阿新 • • 發佈:2018-12-12
【題目】
【題意】
給出整數a,b ,k,a,b代表[a,b]區間,求出最小的長度l,使得[a,b]區間內任何一個長度為l的連續區間中素數的數量>=k.
【思路】
用線性篩法篩出[1,1e6]中的素數,用一個數組cou[i]記錄1到i的素數數目,便於進行某個區間素數數目的計算。由於答案具有單調性,考慮用二分判斷並輸出最小長度l。
【程式碼】
#include <stdio.h> #include <string.h> #include <math.h> #include <stdlib.h> #include <stack> #include <queue> #include <algorithm> #include <iostream> #define mem(a) memset(a,0,sizeof(a)) #define go(i,a,b) for(int i=a;i<=b;i++) #define og(i,a,b) for(int i=a;i>=b;i--) using namespace std; const int N=1e6; const int inf=0x3f3f3f3f; typedef long long ll; typedef unsigned long long ull; bool num[N+5]; int prime[N+5],cou[N+5]; int a,b,k; void isprime() { memset(num,true,sizeof(num)); num[1]=false; int c=0; for(int i=2;i<=N;i++) { if(num[i]) prime[c++]=i; for(int j=0;j<c&&i*prime[j]<=N;j++) { num[prime[j]*i]=false; if(i%prime[j]==0) break; } } } void init() { isprime(); mem(cou); for(int i=2;i<=N;i++) if(num[i]) cou[i]=cou[i-1]+1; else cou[i]=cou[i-1]; } int cul(int l) { for(int i=a;i<=b-l+1;i++) if(cou[i+l-1]-cou[i-1]<k) return 0; return 1; } main() { init(); while(~scanf("%d%d%d",&a,&b,&k)) { int l=1,r=b-a+1,mid,f=0; while(l<=r) { mid=(l+r)/2; if(cul(mid)) r=mid-1,f=1; else l=mid+1; } if(f) printf("%d\n",l); else printf("-1\n"); } }