zoukankan      html  css  js  c++  java
  • POJ 2456 (二分)

    题目链接http://poj.org/problem?id=2456

    题目大意:n个房子,m头牛,房子有一个横坐标,问将m头牛塞进房子,每两头牛之间的最大间隔是多少。

    解题思路

    不难看出应该二分房子间隔,找一个最大的可行间隔。

    首先将房子坐标排序,这样只需从第1个房子开始塞牛就行了,且第一个房子肯定得塞一只牛,才能保证空间的有效利用。

    这样,每次对于一个间隔,从第一个房子开始塞牛:

    ①如果上一个房子坐标last+间隔<=h[i],那么这个房子肯定得塞牛,才能有效利用空间,更新last,cnt++。

    ②否则不能塞牛,去下一个房子。

    这样,只要最后cnt>=m,这个间隔就是可行的。

     

    关键在于确定二分的边界,左边界l可以确定是排序之后相邻两个房子的差的最小值。这也是可以尝试的最小间隔。

    我一开SB地认为右边界就是两个相邻两个房子差的最大值。其实不对,因为牛之间可以隔好多房子。其实r=h[n]-h[1]/(m-1)

    如果你比较机智而且又懒,其实l=0,r=h[i]就行了,反正范围大点也不会超时orz。

    以后确定范围直接脑残0~最大好了。

     

    #include "cstdio"
    #include "algorithm"
    using namespace std;
    int h[100005],n,m,ans;
    bool check(int dist)
    {
        int cnt=1,last=h[1];
        for(int i=2;i<=n;i++) if(last+dist<=h[i]) {last=h[i];cnt++;}
        if(cnt>=m) return true;
        else return false;
    }
    int main()
    {
        //freopen("in.txt","r",stdin);
        int l=0x3f3f3f3f,r=-1;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++) scanf("%d",&h[i]);
        sort(h+1,h+n+1);
        for(int i=2;i<=n;i++) l=min(l,h[i]-h[i-1]);
        r=(h[n]-h[1])/(m-1);
        while(l<=r)
        {
            int mid=l+(r-l)/2;
            if(check(mid)) {ans=mid;l=mid+1;}
            else r=mid-1;
        }
        printf("%d
    ",ans);
    }
    13591899 neopenx 2456 Accepted 548K 110MS C++ 661B 2014-11-02 19:22:27
  • 相关阅读:
    python中字典排序,列表中的字典排序
    Python模块:operator简单介绍
    java 物理资源回收 finally与try
    Eclipse相对路径
    java Lambda
    java 匿名内部类
    java File类
    java单例类
    java 创建子类
    jvm运行时数据区域
  • 原文地址:https://www.cnblogs.com/neopenx/p/4069783.html
Copyright © 2011-2022 走看看