ZCMU-1022-Primes on Interval

本文介绍了一种算法,用于解决在给定区间内寻找满足特定素数条件的最短连续子区间的问题。通过筛法预处理素数,并使用二分查找确定符合条件的最小子区间长度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1022: Primes on Interval

Time Limit: 1 Sec   Memory Limit: 128 MB
Submit: 145   Solved: 65
[ Submit][ Status][ Web Board]

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 integer x (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

Everay 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

2 4 2
6 13 1
1 4 3

Sample Output

3
4
-1

【解析】
这道题的话其实真的挺难写的感觉题意理解起来也有点费劲..大致意思就是给出三个正整数a,b,k,求最小的L(1<=L<=b-a+1),并且对于[a,b-L+1]种的任意一个数X,在[X,X+L-1]这L个数中,至少有k个素数。如果不存在满足条件的L,输出-1。那么我们其实就是要判断在这个区间内有多少个数。那这个素数的判定是有点烦的,因为值很大,平常的判断素数的方法肯定不行。这个时候就要用筛法的。这个时间复杂度比较低比较好用。然后就是怎么找L最小的,其实用二分法还是比较好用的不断的去找满足条件了,那就是再往前找如果不满足条件那就往后找。因为你中间位置找L不行了那肯定在后面前面根本不用找了。
#include <stdio.h>
#include <math.h>
#include <string.h>
using namespace std;
#define MAX 1000100
int sum[MAX]={0};
int su[MAX]={0};
int a,b,k;
void panduan()
{
    int i,j;
    for(i=2;i<MAX;i++)
    {
        sum[i]=sum[i-1];//表示前一个区间内有的素数给现在这个区间
        if(su[i]==0)
        {
            sum[i]++;//如果i是素数则这个区间内的素数加1
            for(j=1;i*j<=MAX;j++)//筛法求素数
               su[i*j]=1;
        }
    }
}
int check(int L)
{
    int i;
    for(i=a;i<=b-L+1;i++)
    {
        if(sum[i+L-1]-sum[i-1]<k)
            return 0;
    }
    return 1;
}
int main()
{
    panduan();
    int i,j,left,right,mid,L;
    while(~scanf("%d%d%d",&a,&b,&k))
    {
        if(sum[b]-sum[a-1]<k)//判断a到b的范围内的素数如果小于k那接下来是不可能有它的子区间的素数是大于k的
        {
            printf("-1\n");//这里为什么要用a-1,我们把样例1带入,区间是2到4,如果我们算的是sum[b]-sum[a]那肯定不对
            continue;//如果a是素数呢,那这样相当于你多减去一个素数了
        }
        left=1;
        right=b-a+1;
        while(left<=right)//二分法查找
        {
            mid=(left+right)/2;
            if(check(mid))
            {
                L=mid;
                right=mid-1;//继续寻找小的
            }
            else
            {
                left=mid+1;//往后找到L的几率比较大,如果中间位置不行了的话
            }
        }
        printf("%d\n",L);
    }
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值