zoukankan      html  css  js  c++  java
  • 借书【二分】

    借书【二分】

    题目描述

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

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

    输入格式

    第一行是nn和mm。

    接下来的nn行,每行一个整数aiai表示第ii本书的难度。

    输入格式

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

    输入样例

    6 3

    5

    7

    1

    17

    13

    10

    输出样例

    7

    样例解释

    DilhaoDilhao给了ldxxxldxxx难度为1,10,171,10,17的三本书,ldxxxldxxx挑选难度为1010和1717的两本书,出题复杂度为77;

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

    数据说明

    对于 30%30%的数据: 2≤n≤202≤n≤20;

    对于 60%60%的数据: 2≤n≤10002≤n≤1000;

    对于 100%100%的数据: 2≤n≤1000002≤n≤100000, 2≤m≤n2≤m≤n, 0≤ai≤10000000000≤ai≤1000000000。


    思路分析

    • 题目很好理解,一堆书中给你m本书,选出这m本书中两本书难度差最小的值作为出题的复杂程度,最后输出最大复杂程度,显然是一道最小值最大化的问题,就需要用到二分

    二分从哪里入手

    • 首先可以明确的是这题要对差值处理,考虑到我们要选m本中的最小差值,那么我们完全可以将原数组排序后处理为差分数组,然后两个数的差值从前往后加即可
    • 二分过程:
      • 最大的最小差值为边界,然后判断右边界(显然右边界最大)是否成立,成立即为最优答案,否则再判断mid,进行区间缩小
      • 判断条件:我们只需要看以该值作为最小差值是否能选出m个数即可(即m-1个差值)

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    inline int read(){
       int s=0,w=1;
       char ch=getchar();
       while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
       while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
       return s*w;
    }
    const int maxn=1e5+5;
    int n,m,a[maxn],cf[maxn];
    int Max=0;
    void Init(){
    	n = read(),m = read();   
        for(int i=1;i<=n;i++){
            a[i] = read();
            Max=max(Max,a[i]);
        }
        sort(a+1,a+n+1);
        for(int i=1;i<n;i++){
            cf[i]=a[i+1]-a[i];//cf差分数组
        }
    }
    bool check(int x){ //x为二分过程中枚举的差值
        int cnt=0,ch=0;//ch当前的最大差值
        for(int i=1;i<n;i++){
            ch+=cf[i];
            if(ch>=x){//找到一对差值大于x
                cnt++,ch=0;//从下个位置找下一对
            }
        }
        if(cnt>=m-1)return true; //能够找出m-1个差值
        return false;
    }
    int main(){
        n = read(),m = read();   
        for(int i=1;i<=n;i++){
            a[i] = read();
            Max=max(Max,a[i]);
        }
        sort(a+1,a+n+1);
        for(int i=1;i<n;i++){
            cf[i]=a[i+1]-a[i];//cf差分数组
        }
        int l=0,r=Max;
    	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; //中间值太大,向右缩小区间
        }
        printf("%d
    ",l);//左边界最小,一定符合答案
        return 0;
    }
    

    发量成功减1%

  • 相关阅读:
    VS2008 环境中完美搭建 Qt 4.7.4 静态编译的调试与发布 Inchroy's Blog 博客频道 CSDN.NET
    编写可丢弃的代码
    c++ using namespace std; 海明威 博客园
    解决MySQL server has gone away
    nginx upstream 调度策略
    (2006, 'MySQL server has gone away') 错误解决 dba007的空间 51CTO技术博客
    Linux IO模型漫谈(2) 轩脉刃 博客园
    redis源码笔记 initServer 刘浩de技术博客 博客园
    MySQLdb批量插入数据
    词库的扩充百度百科的抓取你知道这些热词吗? rabbit9898 ITeye技术网站
  • 原文地址:https://www.cnblogs.com/hhhhalo/p/13251356.html
Copyright © 2011-2022 走看看