题目链接:http://codeforces.com/problemset/problem/237/C
解题思路:首先判断是否有解,即判断当L=b-a+1时是否有解,因此时L最大,若此时都无解,则肯定无解。
若有解,则1 ≤ L≤ b - a + 1,二分求最小的L即可。
#include <cstdio>
#include <iostream>
#include <cstring>
#include <set>
#include <cmath>
using namespace std;
typedef long long LL;
const int MaxN = 1e6 + 2;
int prime[MaxN], vis[MaxN], cnt[MaxN];
int pri_cnt;
//筛法求素数
void get_prime() {
int m = (int)sqrt(1000000 + 1);
pri_cnt = 0;
memset(vis, 0, sizeof(vis));
vis[0] = 1;
vis[1] = 1;
for(int i = 2; i <= m; ++i) {
if(!vis[i]) {
prime[pri_cnt++] = i;
for(int j = i * i; j <= 1000005;j += i)
vis[j] = 1;
}
}
}
//预处理求出1-1000000所有的素数,保存在prime数组中,并用cnt[i]数组记录从0到i有多少个素数
void Init() {
get_prime();
cnt[0] = 0;
for(int i = 1; i <= 1000000; ++i) {
if(!vis[i]) cnt[i] = cnt[i-1] + 1;
else cnt[i] = cnt[i-1];
}
}
// 判断当前的l是否满足题目要求
bool Check(int a, int b, int k, int l) {
int r = b - l + 1;
for(int i = a; i <= r; ++i) {
if(cnt[i + l - 1] - cnt[i - 1] >= k)
continue;
else
return false;
}
return true;
}
// 二分求最小的L
int get_ans(int a, int b, int k) {
int L = 1, R = b - a + 1, mid;
while(L <= R) {
mid = (L + R) / 2;
if(Check(a, b, k, mid))
R = mid - 1;
else
L = mid + 1;
}
return L;
}
int main() {
Init();
int a, b, k;
while(~scanf("%d%d%d", &a, &b, &k)) {
if(!Check(a, b, k, b - a + 1))
printf("-1\n");
else
printf("%d\n", get_ans(a, b, k));
}
return 0;
}