Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 8752 | Accepted: 4349 |
Description
Input
Output
Sample Input
5 3 1 2 8 4 9
Sample Output
3
Hint
Huge input data,scanf is recommended.
题意要表达的是:把C头牛放到N个带有编号的隔间里,使得任意两头牛所在的隔间编号的最小差值最大。例如样例排完序后变成1 2 4 8 9,那么1位置放一头牛,4位置放一头牛,它们的差值为3;最后一头牛放在8或9位置都可以,和4位置的差值分别为4、5,和1位置的差值分别为7和8,不比3小,所以最大的最小值为3。
分析:这是一个最小值最大化的问题。先对隔间编号从小到大排序,则最大距离不会超过两端的两头牛之间的差值,最小值为0。所以我们可以通过二分枚举最小值来求。假设当前的最小值为x,如果判断出最小差值为x时可以放下C头牛,就先让x变大再判断;如果放不下,说明当前的x太大了,就先让x变小然后再进行判断。直到求出一个最大的x就是最终的答案。
本题的关键就在于讨论差值的大小。
自己的代码:
#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<string.h>
#define M(i,n,m) for(int i = n;i < m;i ++)
#define N(n,m) memset(n,m,sizeof(n));
using namespace std;
const int MAX = 100010;
int a[MAX],n,m;
bool C(int d)///判断是否满足条件
{
int last = 0;
M(i,1,m)
{
int crt = last + 1;
while(crt < n && a[crt] - a[last] < d)
crt ++;
if(crt == n)
return false;
last = crt;
}
return true;
}
void solve()
{
int x = 0,y = a[n-1] - a[0]; ///分别找出此时对应的x和y的值
while(y - x > 1)
{
int mid=(x+y)/2;
if(C(mid))
x=mid;
else
y=mid;
}
printf("%d\n",x);
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
N(a,0);
M(i,0,n)
scanf("%d",&a[i]);
sort(a,a+n);
solve();
}
return 0;
}
粘贴的代码:
#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<string.h>
using namespace std;
const int MAX = 100010;
int a[MAX],n,m;
bool C(int d)
{
int t = a[0],count = 1;
for(int i = 1;i < n;i ++)
{
if(a[i] - t >= d)
{
count ++;
t=a[i];
if(count >= m)
return true;
}
}
return false;
}
int solve()
{
int x = 0,y = a[n-1] - a[0];
while(x <= y)
{
int mid=(x+y)/2;
if(C(mid))
x=mid + 1;
else
y=mid - 1;
}
return x - 1;
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
for(int i = 0;i < n;i ++)
scanf("%d",&a[i]);
sort(a,a+n);
printf("%d\n",solve());
}
return 0;
}