POJ 2456 Aggressive cows

题目大意:

        农场主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, 笔直的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值