[POJ](2456)Aggressive cows ---二分查找+贪心(查找+贪心)

来源:互联网 发布:淘宝花店 编辑:程序博客网 时间:2024/05/16 09:25
Aggressive cows
Time Limit: 1000MS Memory Limit: 65536KTotal Submissions: 15599 Accepted: 7477

Description

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 312849

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.

解题新知:
       ①题意:农夫有N件牛舍,牛舍排在一条线上,第i号牛舍在xi的位置。但是他的小牛都很疯狂,彼此之间都会互相攻击。农夫为了防止牛之间互相伤害,决定要把每头牛都放在离其他牛尽可能远的牛舍。题目会给你牛舍的位置,牛的数量为2<=C<=N,也就是说如果C==N,那么牛舍就直接上来就放满了。
用一组数据举例:
5    5
1
3
8
4
9                             
       最终输出结果应该为1,为什么呢,因为两头最近的牛不相互攻击的最大距离就是在 3位置和4位置的两头牛,即dmin=1。那么我们知道了其实就是要求最大化最近的两头牛之间的距离!

       ②思路:根据题意,要求最小值最大,我们可以利用二分和贪心结合的思想(类似POJ1064),我们可以猜最近两头奶牛间距离的最大值,每猜一个距离,进行判断,如果答案可行,则猜的距离可以再大些,如果答案不可行,则猜的距离就要再小些。在判断答案是否可行时,可以用cnt来记录匹配到槽的奶牛数,先将第一头奶牛放在第一个槽,然后依次枚举每个槽,当枚举的槽与前一个放奶牛的槽的距离大于等于猜的答案时,cnt加1,最后判断cnt是否大于等于奶牛数即可。

AC代码:
#include<iostream>#include<algorithm>#include<cstdio>#define INF 1000000005typedef long long LL;using namespace std;int n,c;long long x[100005];bool check(LL d){    int cnt=1;    int now=x[0];    for(int i=1;i<n;i++)    {        if(x[i]-now>=d)        {            cnt++;            now=x[i];        }        if(cnt>=c)            return true;    }    return false;}void bSearch(){    LL l=0;    LL r=INF;    LL mid;    while(r-l>1)    {        mid=(l+r)/2;        if(check(mid)) l=mid;        else  r=mid;    }    printf("%lld\n",l);//最终输入结果时,一定是满足条件的,所以要求的d(mid)被赋给了l,那么我们输入l即可}int main(){    while(scanf("%d %d",&n,&c)!=EOF)    {        for(int i=0;i<n;i++)            scanf("%lld",&x[i]);        sort(x,x+n);        bSearch();    }    return 0;}


原创粉丝点击