zoukankan      html  css  js  c++  java
  • CodeForces 237C Primes on Interval

    Description

    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 aa + 1, ..., b (a ≤ b). You want to find the minimum integer l (1 ≤ l ≤ b - a + 1) such that for any integerx (a ≤ x ≤ b - l + 1) among l integers xx + 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 ≤ 106a ≤ b).

    Output

    In a single line print a single integer — the required minimum l. If there's no solution, print -1.

    Sample Input

    Input
    2 4 2
    Output
    3
    Input
    6 13 1
    Output
    4
    Input
    1 4 3
    Output
    -1


    •题意:给你一个闭区间[a,b],求一个最小的L,使得在区间[a,b-L+1]内任取一个数x,可以满足在x,x+1,x+2,……,x+L-2,x+L-1内至少包含k个素数。(1<=a,b,k<=10^6)
     
    •考察内容:筛素数、二分
    •一边筛素数,一边处理出一个前缀和sum
    •sum(i)表示[1,i]中有多少素数
    •那么我们每次查询区间[l,r]中有多少素数,直接查sum[r]-sum[l-1]就可以了
    •接下去我们按照题意,对答案L进行二分就可以了
     
     1 #include <stdio.h>
     2 #include <string.h>
     3 #define maxn 1000010
     4 
     5 int sum[maxn], a, b, k;
     6 bool pri[maxn];
     7 
     8 void init(){//筛法 素数打表
     9     for(int i = 2; i < maxn; i++){
    10         sum[i] = sum[i-1];
    11         if(pri[i])
    12             continue;
    13         sum[i]++;
    14         for(int j = i+i; j < maxn; j += i)
    15             pri[j] = 1;
    16     }
    17 }
    18 
    19 bool check(int mid){
    20     for(int i = a; i <= b-mid+1; i++){
    21         if(sum[i+mid-1] - sum[i-1] < k)
    22             return 0;
    23     }
    24     return 1;
    25 }
    26 
    27 int main(){
    28     init();
    29     scanf("%d%d%d", &a, &b, &k);
    30     if(sum[b] - sum[a-1] < k){
    31         printf("-1
    ");
    32         return 0;
    33     }
    34     int l = 1, r = b-a+1, ans;
    35     while(l <= r){
    36         int mid = (l+r)>>1;
    37         if(check(mid))
    38             ans = mid, r = mid-1;
    39         else
    40             l = mid+1;
    41     }
    42     printf("%d
    ", ans);
    43 }
  • 相关阅读:
    poj 2100 尺取法 一个数字拆成连续数字平方和
    poj 1011 dfs+剪枝
    CF-242-C bfs+stl
    hdu 1297 递推
    poj 2104 划分树模板
    poj 3842 全排列+筛素数+暴力
    hdu 1421 经典dp
    hdu 1069 最长上升子序列变形
    hdu 3496 二维费用的01背包
    nyoj 16 最长上升子序列变形
  • 原文地址:https://www.cnblogs.com/zzy9669/p/3871588.html
Copyright © 2011-2022 走看看