题目大意:
农场主John建造了一个新的牛棚,里面有N个牛栏(2 ≤ N ≤ 100,000),这些牛栏位于一条坐标轴上,坐标值的范围为[0, 1,000,000,000],各牛栏的坐标互不相同,他共有C头牛(2 ≤ C ≤ N),但是这些牛不满意这样的牛栏格局并且变得非常暴躁,如果把它们随意放入牛栏则相邻的牛可能会发生斗殴,因此John希望把牛放入牛栏后(每个牛栏只能放一头牛)相邻两牛之间的最短距离要最大。
现只有一个测例,测例中给出N、C和各牛栏的坐标,现求最短间距的最大值。
注释代码:
/*
* Problem ID : POJ 2456 Aggressive cows
* Author : Lirx.t.Una
* Language : C++
* Run Time : 110 ms
* Run Memory : 524 KB
*/
#include <stdlib.h>
#include <stdio.h>
#define TRUE 1
#define FALSE 0
//maximum number of stalls
//牛棚的最大数量
#define MAXSTALLN 100000
int loc[MAXSTALLN];//location,记录每个牛棚的位置坐标
int
fcmp(const void *a, const void *b) {
return *(int *)a - *(int *)b;
}
int
xlim( int gap, int n, int c ) {//exceed limit
//计算如果间距为gap是否可行
//即gap会不会太大使得超过最远牛棚的距离
//前提是牛棚的位置已经是从小到大排列好了
//previous and next location of stall
//前一个选中的牛棚和后一个选中的牛棚的编号
int pre, nxt;
int i;//计数变量
//由于有c头牛,因此需要c - 1个gap间距才行
for ( pre = 0, i = 1; i < c; i++ ) {
nxt = pre + 1;
//nxt从pre之后开始扫描,直到刚好间距≥gap为止
while ( nxt < n && loc[nxt] - loc[pre] < gap )
nxt++;
if ( nxt >= n )//如果越界则表示gap不可行
return TRUE;
pre = nxt;//没越界则继续扫描,直到扫完c - 1个间距为止
}
return FALSE;
}
int
main() {
int n, c;//牛棚数和牛的数量
//[lft, rht]表示间距的可能区间
//mid为当前区间中间距的中间值
//就是对该区间进行二分查找,得到正确答案
int lft, rht, mid;
int i;//计数变量
int ans;
scanf("%d%d", &n, &c);
for ( i = 0; i < n; i++ )
scanf("%d", loc + i);
qsort(loc, n, sizeof(int), &fcmp);//排序以方便扫描一个间距是否可行
//初始化时最小间距当然是1
//最大间距可由( 最远牛棚坐标 - 最近牛棚坐标 - 1 )的方式确定
lft = 1;
rht = loc[n - 1] - loc[0] - 1;
while ( lft <= rht ) {
mid = ( lft + rht ) >> 1;
if ( !xlim( mid, n, c ) ) {//如果可行则再试探更大的间距
ans = mid;
lft = mid + 1;
}
else//如果不可行则试探更小的区间范围
rht = mid - 1;
}
printf("%d\n", ans);
return 0;
}
无注释代码:
#include <stdlib.h>
#include <stdio.h>
#define TRUE 1
#define FALSE 0
#define MAXSTALLN 100000
int loc[MAXSTALLN];
int
fcmp(const void *a, const void *b) {
return *(int *)a - *(int *)b;
}
int
xlim( int gap, int n, int c ) {
int pre, nxt;
int i;
for ( pre = 0, i = 1; i < c; i++ ) {
nxt = pre + 1;
while ( nxt < n && loc[nxt] - loc[pre] < gap )
nxt++;
if ( nxt >= n )
return TRUE;
pre = nxt;
}
return FALSE;
}
int
main() {
int n, c;
int lft, rht, mid;
int i;
int ans;
scanf("%d%d", &n, &c);
for ( i = 0; i < n; i++ )
scanf("%d", loc + i);
qsort(loc, n, sizeof(int), &fcmp);
lft = 1;
rht = loc[n - 1] - loc[0] - 1;
while ( lft <= rht ) {
mid = ( lft + rht ) >> 1;
if ( !xlim( mid, n, c ) ) {
ans = mid;
lft = mid + 1;
}
else
rht = mid - 1;
}
printf("%d\n", ans);
return 0;
}
单词解释:
barn:n, 仓库,畜棚
stall:n, 货摊,畜栏
straight:adj, 笔直的