二分法c++

二分法c++

什么是二分法:

百度百科是这样说的:

基本思想:假设数据是按升序排序的,对于给定值x,从序列的中间位置开始比较,如果当前位置值等于x,则查找成功;若x小于当前位置值,则在数列的前半段中查找;若x大于当前位置值则在数列的后半段中继续查找,直到找到为止。

注意:数据必须是排好序的!

详细解释:二分查找

假如有一组数为3,12,24,36,55,68,75,88要查给定的值24.可设三个变量front,mid,end分别指向数据的 上界,中间和下界,mid=(front+end)/2.
1.开始令front=0(指向3),end=7(指向88),则mid=3(指向36)。因为mid>x,故应在前半段中查找。
2.令新的end=mid-1=2,而front=0不变,则新的mid=1。此时x>mid,故确定应在后半段中查找。
3.令新的front=mid+1=2,而end=2不变,则新的mid=2,此时a[mid]=x,查找成功。
如果要查找的数不是数列中的数,例如x=25,当第三次判断时,x>a[mid],按以上规律,令front=mid+1,即front=3,出现front>end的情况,表示查找不成功。

看一下流程图:

再举一个栗子:

Aggressive cows POJ - 2456 

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.

分析:贪心+二分:注意小心TLE:

将本代码改用c++就会TLE!!!!

#include<stdio.h>
#include<string.h>
#include<algorithm>

using namespace std;

int a[100010];
int n,c;
bool judge(int x) {
	int cnt=1;
	int tmp=a[0];
	for(int i=1; i<n; i++) {
		if(a[i]-tmp>=x) {
			cnt++;
			tmp=a[i];
			if(cnt>=c)
				return true;
		}
	}
	return false;
}
int main() {
	while(scanf("%d%d",&n,&c)!=EOF) {
		for(int i=0; i<n; i++)
			scanf("%d",&a[i]);
		sort(a,a+n);
		int l=0,r=a[n-1]-a[0],mid;
		while(l<=r) {
			mid=(l+r)/2;
			if(judge(mid))
				l=mid+1;
			else
				r=mid-1;
		}
		printf("%d\n",l-1);
	}
	return 0;
}

思路比较简单:关键在于:

  • 对于二分法的停止条件:
  • 对于二分法更新L、R的值区间开闭的问题
  • 对于最后输出是L-1而不是L的问题;
  • 使用二分查找的时候需要明确查找对象!
  • 本题中查找的是宽度!也就是数组的值而不是位置; 
  • l相当于做区间左边界,r相当于区间的右边界,m是中间的分界线:一般是:(l+r)/2;
  • 使用循环缩小范围;缩小范围的过程是更新左右边界的过程;
  • 循环停止的条件:左右边界重合的时候,或者左边界大于右边界的时候;
  • 这是最小值最大化问题:先对间隔编号从小到大排序,则最大的距离不会超过两端
  • 两头牛之间的差值,最小值为零。通过二分枚举:设当前最小值为x,如果判断出最西欧啊差值为x是
  • 可以放下c头牛,说明当前的x有点小,x++在判断;若放不下,说明当前的x太大了,就让x--后在进行判断。
  • 知道求出一个最大的x就是最终答案。

并不是所有时候的二分查找的循环停止条件都一致:注意要因题而异!不要思维僵化。

重大发现:是否取等与l更新边界值的方式有关!如果l=mid+1需要取等;如果是l=mid不需要取等!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

加油当当

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值