1. 程式人生 > >POJ2456 Aggressive cows (二分答案)

POJ2456 Aggressive cows (二分答案)

Farmer John has built a new long barn, with N (2 <= N <= 100,000) stalls. The stalls are located along a straight line at positions x1,…,xN (0 <= xi <= 1,000,000,000).

His C (2 <= C <= N) cows don’t like this barn layout and become aggressive towards each other once put into a stall. To prevent the cows from hurting each other, FJ want to assign the cows to the stalls, such that the minimum distance between any two of them is as large as possible. What is the largest minimum distance?

Input

  • Line 1: Two space-separated integers: N and C

  • Lines 2…N+1: Line i+1 contains an integer stall location, xi
    Output

  • Line 1: One integer: the largest minimum distance
    Sample Input
    5 3
    1
    2
    8
    4
    9
    Sample Output
    3
    Hint
    OUTPUT DETAILS:

FJ can put his 3 cows in the stalls at positions 1, 4 and 8, resulting in a minimum distance of 3.

Huge input data,scanf is recommended.

學習二分思想請點選神祕傳送門:https://www.jianshu.com/p/e4a440654946
我覺得做二分答案的題最重要的兩點1.找出答案區間
2.寫出判斷函式
能解決這兩點問題就解決了(但恰恰是最難的)

#include <iostream>
#include <algorithm>
#include <cstdio>
using namespace std;
int n,c;
int a[100010];
int judge(int x)
{
	int now=1; //now代表上一隻牛在哪個牛棚
int cnt=1; //cnt代表安排上的牛的個數 for(int i=2;i<=n;i++) { if(a[i]-a[now]>=x) //判斷函式尤為重要。我們假設的是x是最小距離,那如果下一個牛棚到上一個牛棚的距離比x還要小,顯然不能安排牛,否則,則能安排牛,安排上以後,讓now位置跟上,安排上的牛數量加1 { cnt++;now=i; } } if(cnt>=c) //如果能安排上的牛的數量大於等於我們需要安排的牛的數量1,則這個答案可行(但不一定是最優解,到最後才能得出最優解) return 1; else return 0; } int main() { int L,R,ans; cin>>n>>c; for(int i=1;i<=n;i++) scanf("%d",&a[i]); sort(a+1,a+1+n); L=0;R=a[n]/c+1; //確定答案區間。最小值應該是每個牛棚到初始點的初始距離之差的最小值,這裡嫌麻煩就直接取0了(因為我們確定答案在這個區間內,區間大了沒有關係,但不能小了),而最大值是每個牛之間的平均距離,用離初始點最遠的牛棚的距離除以牛的數量即可,為了保證範圍足夠,讓最大值再加1更為保險。 while(L<=R) { int mid=(L+R)/2; if(judge(mid)) { ans=mid; L=mid+1; //為什麼答案滿足要繼續在右邊找?因為題目想要的是“牛都被安排且每頭牛之間的最小距離儘量大” } else R=mid-1; } cout<<ans<<endl; return 0; }