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