POJ 2456 && SPOJ–AGGRCOW 二分法

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

t – the number of test cases, then t test cases follows.
* Line 1: Two space-separated integers: N and C
* Lines 2..N+1: Line i+1 contains an integer stall location, xi

Output

For each test case output one integer: the largest minimum distance.

Example

Input:

1
5 3
1
2
8
4
9

Output:

3

Output details:

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

————————————————————————————————————————————————————————

  这是心态爆炸比赛的第三题,我看了这道题,机智的把这道题给抽象化成为给你一个序列有n-1个元素,序列中每个元素是相邻两个小屋的距离,然后你对于每个元素的操作是可以把这个元素和相邻的元素合并,问合并到c个元素时可以达到的最大的最小元素是多少。

  然后每次找到最小的元素,并将它们和左右两边中较小的一个元素合并,检查数量有没有到c,没有的话继续……】

  然后可想而知这个抽象结构对于问题的解决方式相比二分查找慢多少……不过我突然发现这个思路虽然不能拿来做题但是可以拿来坑人哎!你看看这题面和二分根本没有关系吧!

  真是开心……个鬼啊……

  好了我们来讲讲题面

  这道题就是用二分来做的,至于为什么没第一眼想到二分,是因为我已经好久没有接触过二分的题目了,对于10^9进行二分搜索,每次判断一下,log2(10^9)差不多是33左右,也就是说进行33次判断无论如何都能找到目标。

  然后这里关于二分的边界需要特判一下,除了lef为1的情况以外,每次的开始,lef左边的那个数必然是满足让全部牛住进去的条件的,但是右边有可能会存在满足条件且更大的数,这个状况一直持续到lef和rig是相邻的情况为止,因为二分的特性,rig的右边不可能存在满足条件且更大的数字,那么只有rig本身是一种可能,这时候就特判一下,如果rig满足条件,输出rig,不然输出lef.

_____________________________________________code_____________________________________________

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<vector>
#include<algorithm>
#include<string>
#include<queue>
#include<climits>
#include<map>
#include<stack>
#include<cmath>
#define file_in freopen("in.txt","r",stdin)
#define MAX 200000
#define maxn 5005
using namespace std;
#define LL int
#define FF(x,y) for(int i=x;i<y;i++)
vector<int>sta;
int s, c;
int bin(int tar)
{
    int temp = sta[0];
    int cnt = 0;
    for (int i = 1; i < s; i++)
    {
        if (sta[i] - temp >= tar)
        {
            temp = sta[i];
            cnt++;
        }
        if (cnt == c-1)
            return 1;
    }
    return 0;
}
void solve()
{
    int lef = 1, rig = sta[s - 1];
    while (1)
    {
        int mid = (lef + rig) >> 1;
        int res = bin(mid);
        if (lef == rig)
        {
            if (res)
            {
                printf("%d\n", lef);
                return;
            }
            else
            {
                printf("%d\n", lef - 1);
                return;
            }
        }
        if (res)
            lef = mid + 1;
        else
            rig = mid - 1;
       
    }   
}
int main()
{
    int t;
    scanf("%d", &t);
    while (t--)
    {
        scanf("%d %d", &s, &c);
        sta.resize(s);
        for (int i = 0; i < s; i++)
            scanf("%d", &sta[i]);
        sort(sta.begin(), sta.end());
        solve();
    }
}
/*
Example

Input:

1
5 3
1
2
8
4
9
Output:

3
*/

posted @ 2017-02-27 15:33  duskcloudxu  阅读(184)  评论(0编辑  收藏  举报