【二分】关于二分法的一些总结
2012-12-17 10:01
197 查看
这里写一些我对二分法的一些心得吧。好像大家写二分都会写得比较囧,上下界弄错~TLE什么的。
先写一下整数二分的:
【下面的程序都是在区间[l,r]上查找x,默认数据顺序非递减】
(1)二分查找区间内某个数字的下标(存在且唯一),不存在返回-1:
这应该是最好写的二分了,注意条件l<=r不是l<r就好。没啥多说的,一看就明白了。
其实这个程序稍微改一下就可以变成查询某个数字出现的最早下标和最晚下标了。
(2)查询区间内<=x的最大值(有多个最大值时返回最靠右的坐标):
二分过程不多说,注意两点:
①假设要在[l,r]上查询那么建议传进去的参数是l-1.r,这样如果返回值为l-1则说明不存在<=x的值,或者可以选择在二分前选判断,确定存在解时再二分。
②mid=(l+r+1)>>1而不是mid=(l+r)>>1,如果取后一种方式的话,假设区间缩小到2、3,此时mid=2,此时如果a[mid]<=x成立那么l=mid,这样会变成死循环,所以要+1再除2。
(3)查询区间内>=x的最小值(有多个最小值时返回最靠左的坐标):
和(2)基本一样的程序,只是条件变成了r=mid和l=mid+1,因此mid要改成mid=(l+r)>>1,否则也会死循环。查询区间[l,r]则传参l,r+1,同样返回值为r+1时为无解。
这样只要控制好上下界和取中间的条件就可以1Y掉二分了。
实数上的二分比较好写,根据题目要求的精度控制一下边界就好,一般不会出现死循环的情况的。
可能有些题精度卡的比较欢乐可以采用循环的方式控制精度,事实上就算是在实数域二分的收敛也是非常快速的,将二分执行几百次基本上都可以收缩到解。
先写一下整数二分的:
【下面的程序都是在区间[l,r]上查找x,默认数据顺序非递减】
(1)二分查找区间内某个数字的下标(存在且唯一),不存在返回-1:
int search(int l,int r,int x) { int mid; while (l<=r) { mid=(l+r)>>1; if(a[mid]==x) return mid; if(a[mid]<x) l=mid+1; else r=mid-1; } return -1; }
这应该是最好写的二分了,注意条件l<=r不是l<r就好。没啥多说的,一看就明白了。
其实这个程序稍微改一下就可以变成查询某个数字出现的最早下标和最晚下标了。
(2)查询区间内<=x的最大值(有多个最大值时返回最靠右的坐标):
int search(int l,int r,int x) { int mid; while (l<r) { mid=(l+r+1)>>1; if(a[mid]<=x) l=mid; else r=mid-1; } return l; }
二分过程不多说,注意两点:
①假设要在[l,r]上查询那么建议传进去的参数是l-1.r,这样如果返回值为l-1则说明不存在<=x的值,或者可以选择在二分前选判断,确定存在解时再二分。
②mid=(l+r+1)>>1而不是mid=(l+r)>>1,如果取后一种方式的话,假设区间缩小到2、3,此时mid=2,此时如果a[mid]<=x成立那么l=mid,这样会变成死循环,所以要+1再除2。
(3)查询区间内>=x的最小值(有多个最小值时返回最靠左的坐标):
int search(int l,int r,int x) { int mid; while (l<r) { mid=(l+r)>>1; if(a[mid]>=x) r=mid; else l=mid+1; } return l; }
和(2)基本一样的程序,只是条件变成了r=mid和l=mid+1,因此mid要改成mid=(l+r)>>1,否则也会死循环。查询区间[l,r]则传参l,r+1,同样返回值为r+1时为无解。
这样只要控制好上下界和取中间的条件就可以1Y掉二分了。
实数上的二分比较好写,根据题目要求的精度控制一下边界就好,一般不会出现死循环的情况的。
while (fabs(r-l)>EPS)//EPS是题目要求的精度 { mid=(l+r)/2; if(check(mid)) l=mid; else r=mid; }
可能有些题精度卡的比较欢乐可以采用循环的方式控制精度,事实上就算是在实数域二分的收敛也是非常快速的,将二分执行几百次基本上都可以收缩到解。
for(int i=1;i<=200;i++) { mid=(l+r)/2; if(check(mid)) l=mid; else r=mid; }
相关文章推荐
- 关于Cookie跨域操作的一些总结
- 关于RDLC报表的一些总结,希望对正在学习使用它的朋友有所帮助
- 关于游戏开发的一些总结
- 关于juery一些用法自己的总结
- 关于java编程中一些编程安全问题的总结
- 关于做项目的一些总结
- 关于sqlite3使用top的一些规则总结
- 关于工作的一些总结
- 关于面试的一些总结
- linux 中关于循环难得一些语句总结
- 关于 Android Dex 方法限制的一些总结
- 关于《ASP.NET办公自动化系统开发实例导航》问题的一些总结
- 关于self.用法的一些总结
- 关于系统架构的一些总结(1)
- 黑马程序员关于Ado。Net的一些总结
- 关于进制数的一些概念总结.
- 关于iphone http上传请求协议的一些总结
- 关于Java中的继承与访问修饰符的一些总结
- 关于self.用法的一些总结
- 关于软件研发的一些体会总结