zoukankan      html  css  js  c++  java
  • 【洛谷习题】丢瓶盖

    题目链接:https://www.luogu.org/problemnew/show/P1316


    刷新我对二分答案理解的二分答案题!

    根据问法这是道二分答案题,嗯事实证明确实如此。然后我们分两个过程研究。

    第一是二分边界的处理。之前我一直使用的是闭区间,结果在这翻车了,我之前还以为闭区间是万能的,左闭右开是不完美的!!!额,原因在于闭区间对于边界的处理十分严格,编程语言的缘故,就会出现死循环等不可描述的错误。

    解决办法是区间不要卡得太严格,要写成mid=l+(r-l+1)/2。当然也可以改成左闭右开,就比较自然了。后来发现,其实两种方法在不同的情况下并不一定正确,一个比较不正式的方法是,两种方法都试试。

    第二点就是验证了。一开始我很纠结,两个瓶盖的最短距离必须保证存在啊,仔细考虑后发现,最大的最短距离一定是存在的,就是说一定有两个瓶盖的距离是他,否则,会存在两个瓶盖的距离比这个答案还大。

    再就是,验证时,我们从1开始暴力验证,能取就取,真的对吗?应该是对的,要么符合答案的取法里有1,要么没有,如果没有,若答案会取的那个在1的下一块之后,那么和1就没有什么关系了,若刚好是1的下一块,显然取1会更优(当然,如果答案不是1和其下一块的距离,和1就更没有关系了)。

    呃呃,还要注意将坐标排序,题目描述并不保证是顺序的。

     1 #include <cstdio>
     2 #include <algorithm>
     3 
     4 using namespace std;
     5 
     6 const int maxn = 1e5 + 5;
     7 
     8 int a, b, cap[maxn];
     9 
    10 inline int min(int a, int b) {return a < b ? a : b;}
    11 
    12 inline int check(int x) {
    13     int cnt = 1, last = 1;
    14     for (int i = 2; i <= a; ++i)
    15         if (cap[i] - cap[last] >= x) ++cnt, last = i;
    16     if (cnt >= b) return 1;
    17     else return 0;
    18 }
    19 
    20 int main() {
    21     scanf("%d%d", &a, &b);
    22     for (int i = 1; i <= a; ++i)
    23         scanf("%d", &cap[i]);
    24     sort(cap + 1, cap + a + 1);
    25     int l = 0, r = cap[a] - cap[1], mid;
    26     while (l < r - 1) { //左闭右开写法
    27         mid = l + (r - l) / 2;
    28         if (check(mid)) l = mid;
    29         else r = mid;
    30     }
    31     printf("%d", l);
    32     return 0;
    33 }
    AC代码
  • 相关阅读:
    Centos 7安装配置NTP网络时间同步服务器
    Git忽略提交规则 .gitignore配置运维总结
    linux scp放后台执行方法
    《Linux Kernel Development》读书笔记PDF下载(2012.5.7最后更新)
    D4整体架构差不多快出来了
    c#实现IOleCommandTarget接口(原闯)
    centos7一键安装samba服务器
    R语言绘图高质量输出
    R语言与数据分析
    R语言Cairo包的使用
  • 原文地址:https://www.cnblogs.com/Mr94Kevin/p/9777352.html
Copyright © 2011-2022 走看看