标签:else 整数 check lse 疑问 模板 验证 while pre
之前一直都没有想清楚整数的二分到底是要打算怎么搞。
首先约定二分的区间为[l,r]闭区间。
看一下下面这个实现,由于我们的约定,所以l与r都要取能取到的(合法的)值。
#include<bits/stdc++.h> using namespace std; int main(){ int n; while(~scanf("%d",&n)){ int l=1,r=1000000; int m; while(l<r){ m=(l+r)>>1; printf("%d\n",m); if(m<n){ l=m+1; } else{ r=m; } } printf("ans=%d\n",l); } }
由于我们约定是在[l,r]闭区间去找的,所以当中间点m<n的时候,认为中间点过小,把l改成m+1(因为m也取不到),反之把r改成m。
那么毫无疑问最后的一次操作中l与r的距离恰好是1。此时我们取得的m恰好为l,验证m小之后把l改成m+1也就是r,反之则答案就是l。所以上述的写法是正确的。
总结:整数的二分,闭区间[l,r],while(l<r),判断的是必须是<符,答案是l。
那么假如我们是用check(m)呢,也就是说询问m是否符合要求?这东西情况就复杂多了,根据你要找的值是最大还是最小感觉还不一样。我们可以实现查找在区间中等于n的第一个或者最后一个。
依然约定是闭区间[l,r],while(l<r),仿照上面对l与r进行收缩,最终会使l与r相差恰好为1,这时还是根据自己要求的是较大还是较小特判一下退出最好。
标签:else 整数 check lse 疑问 模板 验证 while pre
原文地址:https://www.cnblogs.com/Yinku/p/10319223.html