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 ,最后就得到答案啦

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM