您的位置:首页 > 其它

二分入门——poj 2456 aggressive cows

2016-10-31 19:59 239 查看
这是一道二分的神奇贪心题,先上题目

Aggressive cows

Time Limit: 1000MS Memory Limit: 65536K

Total Submissions: 11714 Accepted: 5732

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 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.

题目翻译:

大概就是说fj与他的牛相爱相杀,fj要给牛建棚子,每个棚子都在一条直线上,都有不同的坐标,但是牛并不喜欢跟其他的牛住得太近,所以要求找出最小的最大距离。

输入:

一个棚子数,一个牛数。

输出:

最小的最大距离。

这个题很多人先懵在最小最大距离上,这个我们图示样例看一看:


所以,我们要找的最优解就是一个放1,一个放4,一个9。

最小的距离就是4-1=3。

这样的意思就是让牛们住得最分散,找出最小的距离。

然后我们考虑到算法上去。

代码(注释详解代码):

#include<stdio.h>
#include<cmath>
#include<vector>
#include<functional>
#include<queue>
#include<string.h>
#include<algorithm>
#include<iostream>
using namespace std;
const int maxn=100011;

struct cmp{
bool operator()(int &a,int &b)
{
return a>b;
}
};//这是一个优先队列的比较函数。

int n,c,k;
int array[maxn],qu[maxn];
int main()
{
priority_queue<int,vector<int>,cmp>que;//让优先队列从小到大排序。
cin>>n>>c;
for(int i=1;i<=n;i++)
{
int x;
cin>>x;
que.push(x);
}
for(int i=0;i<n;i++)
{
array[i]=que.top();
que.pop();
}
//以上为输入,将输入的牛棚按与原点的距离排一遍
int ls=0,rs=1e9;//二分套路,总在一个范围内进行寻找。这里没有办法知道最大值可能是什么情况,所以用一个1e9代替。
while(rs-ls>1)
{
int midd=(rs+ls)/2;
//以下为算法核心
int find=0,flag=1;//先找一个标识变量find和一个判断变量flag
for(int i=1;i<c;i++)//因为寻找的是距离,所以遍历的次数是总数-1
{

int cnt=find+1; // 而且我们默认了第一头牛在第一个棚子里
while(cnt<n &&array[cnt]-array[find]<midd)
{
cnt++;
}
if(cnt==n)
{
flag=0;
break;
}
else
find=cnt;//这个地方是比较神奇的,我们先默认了第一个牛在第一个棚子里,然后让他开始找,跟每一个标识find进行比较,如果小于midd,就让cnt++;
//当cnt在重复的比较中满足了条件,一直加到了n,就是能找到小的,就break。
}

if(flag)//他满足了条件,就说明要么是找到了,要么是找小了,就让它等于ls,接着二分进去。
{
ls=midd;
}
else
{
rs=midd;
}
//***********
}
cout<<ls<<endl;
return 0;
}


其实这个题的输出更是一个神奇的东西,这里输出要输出ls,因为我们每次都是在满足条件的情况下让ls=midd,所以,即使找到了答案,也是ls找到的,故要输出ls。

这个二分题应该已经不是入门难度了……
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  poj