20181029noip模拟赛T1

1、借书

【问题描述】

Dilhao一共有n本教科书,每本教科书都有一个难度值,他每次出题的时候都会从其中挑两本教科书作为借鉴,如果这两本书的难度相差越大,Dilhao出的题就会越复杂,也就是说,一道题的复杂程度等于两本书难度差的绝对值。

这次轮到ldxxx出题啦,他想要管Dilhao借m本书作为参考去出题,Dilhao想知道,如果ldxxx在Dilhao给出的m本书里挑选难度相差最小的两本书出题,那么ldxxx出的题复杂程度最大是多少?

【输入格式】

 第一行是n和m。

 接下来的n行,每行一个整数ai表示第i本书的难度。

【输入格式】

 一个整数为ldxxx出的题复杂程度的最大值。

【输入样例】

6 3

5

7

1

17

13

10

【输出样例】

7

【样例解释】

Dilhao给了ldxxx难度为1,10,17的三本书,ldxxx挑选难度为10和17的两本书,出题复杂度为7;

如果Dilhao给出其他任何三本书,其中的两本书难度差的最小值都小于7,所以ldxxx出题最大的复杂程度为7。

【数据说明】

对于 30%的数据: 2<=n<=20;

对于 60%的数据: 2<=n<=1000;

对于 100%的数据: 2<=n<=100000, 2<=m<=n, 0<=ai<=1000000000。

思路:

一眼题

对于原数组,我们可以将它差分

然后二分一个答案出来

扫一遍原序列验证即可

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define rii register int i
#define rij register int j
using namespace std;
int n,m,x[100005],cha[100005];
bool cmp(int lk,int kl)
{
    return lk<kl;
}
bool check(int val)
{
    int jsq=0,ch=0;
    for(rii=1;i<n;i++)
    {
        ch+=cha[i];
        if(ch>=val)
        {
            jsq++,ch=0;
        }
    }
    if(jsq>=m-1)
    {
        return true;
    }
    return false;
}
int main()
{
    freopen("margin.in","r",stdin);
    freopen("margin.out","w",stdout);
    scanf("%d%d",&n,&m);
    int r=0,l=0;
    for(rii=1;i<=n;i++)
    {
        scanf("%d",&x[i]);
        r=max(r,x[i]);
    }
    sort(x+1,x+n+1,cmp);
    for(rii=1;i<n;i++)
    {
        cha[i]=x[i+1]-x[i];
    }
    while(l<=r)
    {
        if(r-l==1)
        {
            if(check(r)==true)
            {
                l=r;
            }
            break;
        }
        int mid=(l+r)/2;
        if(check(mid)==true)
        {
            l=mid;
        }
        else
        {
            r=mid;
        }
    }
    cout<<l;
}
原文地址:https://www.cnblogs.com/ztz11/p/9876884.html