zoukankan      html  css  js  c++  java
  • 1433:【例题1】愤怒的牛

    1433:【例题1】愤怒的牛

    题解

    This is an er'fen ti.

    由题意可得  它是求最小值最大的问题

    我们假设:

            每两头牛之间的最小距离为 d ,也就是每两头牛之间的距离 >= d ,问题也就是求这个 d 最大是多少

    理一理思路

    1.对所有的牛舍从小到大排序

    2.假设我们把第 i 头牛放在 ai 号牛舍里,那么第 i+1 头牛就要放在 ai+d<=a的ak 牛舍中,由于可能有很多牛舍满足条件,我们 选取距离 ai 最近的一个(这是很显然的,因为这样对后面的选择影响小),然后依次类推,放牛,  放牛,放牛。。。

       Ps:举个栗子解释一下为什么显然:

        假设John有3头奶牛要放,他有10个牛舍,那么我们应该怎么安排呢???

    我们先假设答案d等于多少,然后再不断调整答案,得到最终结果

    下面看图

       

        按照思路,我们应该把cow2放在4号,但是我们就不,我们看看会有什么后果

      好啦,显然,我们应该按照思路走:选取距离 a最近的一个

     

    3.由于只需要在开头对数组进行一次sort排序,后面每次判断对每头牛只需要进行一次处理,时间复杂度为O(nlogn)

    (注释在代码后面o)

    代码

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #include<string>
    
    using namespace std;
    
    const int maxn=1e5+1;
    int n,c;
    int a[maxn];
    
    bool check(int d)    //注释5
    {
        int cow=1;
        int now=a[1]+d;
        for(int i=2;i<=n;i++)
        {
            if(a[i]<now) continue;
            cow++;
            now=a[i]+d;
        }
        return cow>=c;
    }
    
    int main()
    {
        scanf("%d%d",&n,&c);
        for(int i=1;i<=n;i++)
           scanf("%d",&a[i]);     
        
        sort(a+1,a+n+1);      //注释1
        
        int l=0,r=a[n]-a[1];  //注释2
        while(l<=r)
        {
            int mid=(l+r)>>1;  //注释3
            if(check(mid)) l=mid+1;   //注释4
            else r=mid-1; 
        }
        
        printf("%d",r);
        
        return 0;
    }

    注释

    1.输入数据,然后排序一下牛舍

    2.初始化一下 L 为0,r 其实就是最后的结果,初始化为第一个牛舍与最后一个牛舍的距离

    3.mid为暂定的那个最小距离(也就是博客开始的那个 d ),二分常规操作,(l+r)÷2

    4.拿着mid去函数check里看一看(建议结合一下注释5看check的用法)

     (1)最小距离定为这个mid,cow可以放下的数目>=规定数目,那么说明这个mid可以再大一点, 更新 l 

     (2)最小距离定位这个mid,牛舍不能放下约翰的牛喽,那就说明这个距离就要缩小一点啦,更新 r 

    5.自定义check函数

    (1)我们放了第一个cow

    (2)下一个cow就要放到>=的牛舍里距离上一个cow最近的牛舍中了

    (3)for循环,计算可以放入cow的数目

    (4)返回的数值用于注释4

    6.不断二分啊二分啊,l 就无限逼近  r ,最后就得到答案啦

  • 相关阅读:
    图形
    附属信息
    文件操作
    字符编码
    Python数据类型之基础记。。。
    python并发编程之多进程
    python并发编程之多进程
    计算机基础之计算机系统的简单了解。
    元类
    基于socketserver模块实现并发tcp/udp
  • 原文地址:https://www.cnblogs.com/xiaoyezi-wink/p/10989190.html
Copyright © 2011-2022 走看看