題解 進擊的奶牛 洛谷P1824

2021-10-06 09:38:24 字數 1718 閱讀 8026

題目請戳:洛谷p1824 進擊的奶牛

farmer john建造了乙個有n(2<=n<=100,000)個隔間的牛棚,這些隔間分布在一條直線上,座標是x1,…,xn (0<=xi<=1,000,000,000)。

他的c(2<=c<=n)頭牛不滿於隔間的位置分布,它們為牛棚裡其他的牛的存在而憤怒。為了防止牛之間的互相打鬥,farmer john想把這些牛安置在指定的隔間,所有牛中相鄰兩頭的最近距離越大越好。那麼,這個最大的最近距離是多少呢?

第1行:兩個用空格隔開的數字n和c。

第2~n+1行:每行乙個整數,表示每個隔間的座標。

輸出只有一行,即相鄰兩頭牛最大的最近距離。

輸入

5 3

1 2

8 4

9

輸出
3
首先牛棚的分布是x1,...,xn (0<=xi<=1,000,000,000),1010

10^10

10< 108

10^8

108 暴力肯定會tle

那麼我們如何減少時間複雜度呢。列舉每一種可行解是不大可行了。但是如果給出乙個猜測解,去驗證這個解是否可行就容易得多。也就是我們先在範圍x1~xn內隨便猜乙個可能的間隔mid,然後驗證如果每兩頭牛之間至少相鄰mid個牛棚是否可行。

如果這個mid可行,則不用考慮比它小的解了(比mid小的解可能可行,但題目要求的是最大的可行mid)如果我們取的mid位於可行區間中點左右的位置,一下就排除了一半!!(雨巨:「是不是很快樂!!」 ๑乛◡乛๑)

而如果當前猜測的mid不可行,則比它大的解也不用考慮了(因為一定不可行)

於是我們的思路從列舉尋找兩頭最近牛之間的最大距離,變成了給乙個距離判斷這個距離是否可行。

(好啦二分的思路講完啦)

簡單地說,就是每次取乙個臨近中點的點,判斷這個點的值是否滿足條件。是則取這個點的右半邊繼續上述過程。否則取這個點的左半邊繼續上述過程。

接下來上**:

#include

#include

#include

using namespace std;

int n,a[

100005

],c;

intcheck

(int low,

int high)

while

(a[i]

< tar && i < n)

//找到下乙個滿足距離的隔間

i++; cow--;}

if(flag)

//更新可行解的區間[low,high)

low = dis;

else

high = dis;

}return dis;

}int

main()

其實check和二分是可以分開的看起來清楚一些。我直接混在一起寫了乙個函式。

順帶一提。判斷邊界或者返回值最好的辦法就是帶幾組資料進去試一下。還可以用我這組樣例試試:

輸入

5 3

1 2

6 4

5

輸出
2

洛谷P1824進擊的奶牛

題目描述 farmer john建造了乙個有n 2 n 100,000 個隔間的牛棚,這些隔間分布在一條直線上,座標是x1,xn 0 xi 1,000,000,000 他的c 2 c n 頭牛不滿於隔間的位置分布,它們為牛棚裡其他的牛的存在而憤怒。為了防止牛之間的互相打鬥,farmer john想把...

洛谷 P1824 進擊的奶牛

原題 farmer john建造了乙個有n 2 n 100,000 個隔間的牛棚,這些隔間分布在一條直線上,座標是x1,xn 0 xi 1,000,000,000 他的c 2 c n 頭牛不滿於隔間的位置分布,它們為牛棚裡其他的牛的存在而憤怒。為了防止牛之間的互相打鬥,farmer john想把這些...

洛谷 P1824 進擊的奶牛

又是一道二分答案啊 如果發現題意是 最小值最大 最大值最小 最優解 那麼就要思考是不是用二分答案寫了 其實還是一道跳石頭 奶牛跳房子 不懂可以看下這題我的題解 建議先做做跳石頭 把牛棚當作石頭,把牛的總數當作必須有的石頭數,那麼牛棚總數減去牛的總數就是可以移開石頭的個數 然後就是跳石頭啦 但寫法有一...