今天刷了NOIoj上的几道二分题,借此小结一下今天学到的东西;
1.二分查找模板
while(l<=r){ int mid=l+r>>1; if(a[mid]==x){ cout<<x<<endl; break; } else if(a[mid]>x) r=mid-1; else l=mid+1; }
亲测很实用
2.二分答案模板
模板一:求最大值
while(l<r){ int mid=l+r+1>>1; if(check(mid)) r=mid-1; else l=mid; }
可解决的问题有
1.最小值的最大值
2.符合条件的最大值
模板二:求最小值
while(l<r){ int mid=l+r>>1; if(check(mid)) r=mid; else l=mid+1; }
可解决的问题有
1.最大值的最小值
2.符合条件的最小值
面对整数的万能模板
while(l<=r){ int mid=l+r>>1; if(check(mid)){ ans=mid; r=mid-1; } else l=mid+1; }
推荐这种,因为上面两个我还是理解不了(tcl)
有许多大佬都喜欢写这个板子,因为不容易错
上面是最小值,把模板稍微改一改就能求最大值
3.面对实数二分答案
着实很烦,提前需要定义一个“无限接近于零”的量来控制精度,在二分过程中千万别有像上面一样的+1-1操作,否则会错的很惨(亲测);
直接上模板
const double eps=0.0000001; while(l+0.000001<r){//l,r都是double double mid=(l+r)/2; if(check(mid)) r=mid; else l=mid; }
当然这个模板也有求最大值版
4.今天刷题知道的
1.少看题解!少看题解!少看题解!其实你跟他们写的差不多,只是细节上问题,不过NOIoj很坑,因为它不能下数据,这就要靠自己了
2.double除法用floor取整(这都想不到,别吐槽)
3.输出小数点后若干位时,好像会自动四舍五入(未亲测)
4.PI的表示:别再用3.1415926了,用个高级点的:acos(-1.0),在<cmath>库里
5.注意输出一些文字时的大小写
双十一快乐!!!!!!
p.s.文章中资料引用:https://blog.csdn.net/Mashiro_ylb/article/details/78469151,https://blog.csdn.net/zizizi9898/article/details/89301737
原文:https://www.cnblogs.com/MLETNxtl/p/11839061.html