• 【二分】丢瓶盖


    二分答案

    题目描述

    陶陶是个贪玩的孩子,他在地上丢了A个瓶盖,为了简化问题,我们可以当作这A个瓶盖丢在一条直线上,现在他想从这些瓶盖里找出B个,使得距离最近的2个距离最大,他想知道,最大可以到多少呢?

    输入输出格式

    输入格式:

    第一行,两个整数,A,B。(B<=A<=100000)

    第二行,A个整数,分别为这A个瓶盖坐标。

    这不是2017年衢州市赛的题目么

    借用题解里看到的一句话总结一下:“一般看到所谓的最大值最小化或者最小值最大化,一般都是用二分答案进行运算”作者: Lyrics 

    嗯对了就是这样,二分答案。

    二分答案的题呃普及组的似乎就是这样的套路:找一个上下限;写一个check函数;考虑输出 mid / l / r。最后这个还是视情况而定。

    本题的话,check函数不难写出,不过我卡在了最后的这个输出上面。因为以前有写二分的“阴影”,调试的时候先把三个都列出来了。呃,还有那个调整上下限的问题,我印象里"l=mid"/"l=mid+1"在不同的题目里都有出现。于是乎调整了很久(有调将近二十分钟),最后没有办法打了个类似于补丁一样的东西上去(好吧这的确很不“计算机程序设计艺术”),大号提交的是这份:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 
     4 int a[100035],n,m;
     5 int l,r,mid,lm,la,cnt;
     6 int main()
     7 {
     8     scanf("%d%d",&n,&m);
     9     for (int i=1; i<=n; i++)scanf("%d",&a[i]);
    10     sort(a+1, a+n+1);
    11     l=0;r=a[n]-a[1];lm = -1;
    12     while (l <= r)
    13     {
    14         mid = (l + r) >> 1;
    15         if (mid == lm)break;
    16         la=1;cnt=1;
    17         for (int i=2; i<=n; i++)
    18             if (a[i] - a[la] >= mid){
    19                 cnt++;la = i;
    20             }
    21         if (cnt < m)r = mid-1;
    22         else l = mid+1;
    23         lm = mid;
    24     //    printf("%d %d %d
    ",l,r,mid);
    25     }
    26     {
    27         while(cnt < m)
    28         {
    29             mid--;
    30             la=1;cnt=1;
    31             for (int i=2; i<=n; i++)
    32                 if (a[i] - a[la] >= mid){
    33                     cnt++;la = i;
    34                 }
    35         }
    36     }
    37     printf("%d",mid);
    38     return 0;
    39 } 
    大号份 ViewCode

    嗯,地地道道的丑陋……

    看了一下题解,突然想起来这里求最大值,所以不用费神这么多,输出r就行了。不过当时在前几次的调试之后(调整上下限的还没成型),发现l,r都不对,最后决定改成mid了……

    小号份ViewCode

    噫,好吧二分是不太熟了

     1 笨蛋我的方法
     2 int main()
     3 {
     4     l=0;r=a[n]-a[1];lm = -1;
     5     while (l <= r)
     6     {
     7         mid = (l + r) >> 1;
     8         if (mid == lm)break;
     9         la=1;cnt=1;
    10         for (int i=2; i<=n; i++) ...
    11         if (cnt < m)r = mid-1;
    12         else l = mid+1;
    13         lm = mid;
    14     }
    15     {
    16         while(cnt < m)
    17         {
    18             mid--;
    19             la=1;cnt=1;
    20             for (int i=2; i<=n; i++)
    21                 if (a[i] - a[la] >= mid){
    22                     cnt++;la = i;
    23                 }
    24         }
    25     }
    26     printf("%d",mid);
    27     return 0;
    28 }
    29 
    30 
    31 聪明你的方法
    32     l=0;r=a[n]-a[1];
    33     while (l <= r)
    34     {
    35         mid = (l + r) >> 1;
    36         la=1;cnt=1;
    37         for (int i=2; i<=n; i++)
    38             if (a[i] - a[la] >= mid){
    39                 cnt++;la = i;
    40             }
    41         if (cnt < m)r = mid-1;
    42         else l = mid+1;
    43     }
    44     printf("%d",r);
    45     return 0;
  • 相关阅读:
    引自天天安全网 ——※ 中华民族传统文化精髓___二十四孝 ※
    Microsoft 技术与安全大会
    Linux的用户和用户组管理
    vsftpd设置与使用总结
    MySQL与NoSQL——SQL与NoSQL的融合
    linux下查看用户及用户组的方法
    软件系统开发中的数据交换协议
    Ubuntu实用简单的FTP架设
    淘宝网商品库优化实践访谈
    current attention url
  • 原文地址:https://www.cnblogs.com/antiquality/p/8459991.html
Copyright © 2020-2023  润新知