Aggressive cows

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.

注意要排序。

#include <iostream>
#include <algorithm>
using namespace std;
int a[100010];
int n,m;
int we(int x){
	int sum=0;
	int j=0;
	for(int i=1;i<n;i++){
		if(a[i]-a[j]>=x){
			sum++;
			j=i;
			if(sum>=m-1)
				return 1;
		}
	}
	return 0;
}
int main(){
	scanf("%d %d",&n,&m);
	for(int i=0;i<n;i++){
		scanf("%d",&a[i]);
	}
	sort(a,a+n);
	int r=0,l=(a[n-1]-a[0])/(m-1),min;
	while(r<=l){
		min=(l+r)/2;
		if(we(min)){
			r=min+1;
		}
		else{
			l=min-1;
		}
	}
	printf("%d\n",r-1);//因为当r>l时退出循环时r+1的 
} 


<think>题目要求:在一条直线上有N个牛棚,位置为x1, x2, ..., xN(可能无序)。现在有C头牛,需要将这些牛放置在牛棚中,使得任意两头牛之间的最小距离尽可能大。注意:牛棚位置为整数,但最小距离是整数,因为位置是整数,距离也是整数。 思路: 1. 首先将牛棚位置排序(从小到大)。 2. 使用二分查找来确定最小距离的最大可能值。 3. 二分查找的区间:左边界为0,右边界为最远两个牛棚的距离(即排序后最后一个位置减去第一个位置)。 4. 对于每个中间值mid(即当前假设的最小距离),判断是否能够放置至少C头牛,使得任意两头牛之间的距离都不小于mid。 5. 判断方法(贪心): a. 首先将第一头牛放在第一个牛棚(位置最小的)。 b. 然后遍历后续牛棚,当当前牛棚的位置与前一个放置牛的牛棚位置的距离大于等于mid时,就在当前牛棚放置牛。 c. 如果能够放置的牛的数量大于等于C,则说明mid可行,可以尝试更大的距离(即调整左边界);否则,说明mid太大,需要减小距离(调整右边界)。 6. 由于要求的是最大的最小距离,因此当找到一个可行解时,我们尝试增大距离,所以二分查找中当valid(mid)为真时,我们记录当前mid,并向右区间继续搜索(即low=mid+1),直到找到最大的可行距离。 注意:题目要求使用scanf,因为输入规模大。 代码实现: 我们将使用C++98标准,并且使用gcc4.4.0兼容的语法。 步骤: 1. 输入N和C。 2. 输入N个牛棚的位置,并存储到数组中。 3. 对数组进行排序。 4. 初始化二分查找的左右边界:low=0, high=positions[N-1]-positions[0]。 5. 进行二分查找,对于每个mid,调用验证函数判断是否可以放置C头牛。 6. 验证函数:使用贪心策略,从第一个位置开始,记录上一头牛放置的位置,然后遍历每个位置,如果当前位置与上一头牛的位置距离>=mid,则放置一头牛,并更新上一头牛的位置。最后统计放置的牛的数量是否>=C。 7. 二分查找结束后,输出答案(即最大的最小距离)。 注意:由于最小距离是整数,所以二分查找的mid也是整数。 样例:5 3,位置为1,2,4,8,9。排序后为1,2,4,8,9。 验证距离3:第一头牛放1,第二头牛放4(因为4-1>=3),第三头牛放8(8-4>=3),所以可以放3头牛,返回true。 验证距离4:1放第一头,下一头至少是5,没有5,然后8-1=7>=4,所以第二头放8,然后9-8=1<4,所以只能放2头牛,返回false。 因此,最大的最小距离是3。 代码: </think> ### 解决方案:使用二分查找最大化最小距离(C++98兼容) #### 解决思路 问题要求在一条直线上放置C头牛到N个牛棚中,使得任意两头牛之间的最小距离尽可能大。解决方案采用二分查找算法: 1. **预处理**:将牛棚位置排序 2. **二分查找**: - 左边界:0(最小距离) - 右边界:最大可能距离(最远两个牛棚的距离) 3. **验证函数**:检查给定距离下是否能放置C头牛 4. **贪心策略**:按顺序放置牛,确保每头牛与前一头至少相距给定距离 #### 代码实现(C++98兼容) ```cpp #include <cstdio> #include <algorithm> using namespace std; const int MAX_N = 100000; int positions[MAX_N]; int N, C; // 验证函数:检查是否能以最小距离d放置C头牛 bool canPlace(int d) { int count = 1; // 第一头牛总是放在第一个位置 int last = positions[0]; for (int i = 1; i < N; i++) { if (positions[i] - last >= d) { count++; last = positions[i]; if (count >= C) return true; } } return false; } int main() { scanf("%d%d", &N, &C); for (int i = 0; i < N; i++) { scanf("%d", &positions[i]); } sort(positions, positions + N); int low = 0; int high = positions[N-1] - positions[0]; int ans = 0; while (low <= high) { int mid = low + (high - low) / 2; if (canPlace(mid)) { ans = mid; low = mid + 1; } else { high = mid - 1; } } printf("%d\n", ans); return 0; } ``` ### 代码说明 1. **输入处理**: - 使用`scanf`高效读取输入数据 - 将牛棚位置存储在数组`positions`中 - 对数组进行排序(升序) 2. **二分查找**: - `low`初始为0(最小可能距离) - `high`初始为最大距离(首尾牛棚距离) - 循环条件`while (low <= high)`确保搜索完整区间 - 使用`mid = low + (high-low)/2`防止整数溢出 3. **验证函数`canPlace`**: - 第一头牛固定放在第一个位置 - 遍历后续位置,当距离≥给定值`d`时放置新牛 - 达到C头牛时立即返回`true` - 遍历结束仍未达到C头牛返回`false` 4. **结果输出**: - 记录满足条件的最大距离`ans` - 循环结束后输出最终答案 ### 算法分析 - **时间复杂度**:O(N log D) - 排序:O(N log N) - 二分查找:O(log D),D为最大距离 - 每次验证:O(N) - **空间复杂度**:O(N)存储牛棚位置 - **正确性**:贪心策略保证局部最优解,二分查找最大化最小距离 ### 示例解析 输入样例: ``` 5 3 1 2 8 4 9 ``` 处理过程: 1. 排序位置:[1, 2, 4, 8, 9] 2. 距离范围:[0, 8] 3. 二分查找: - mid=4:无法放置3头牛(只能放1和8) - mid=3:可放置3头牛(1,4,8) 4. 输出结果:3
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值