对于某些问题,如果答案具有特定的范围,并且验证答案是否成立的函数具有单调性。
则可以在范围内对答案进行二分验证,从而快速确定答案。
例:hdu 1969
这题的关键在与对范围进行变换,因为我们一般所遇到的二分都是整数,进行mid+1或mid-1,所以对数字*误差容许的数量级。
具体代码如下:
|
# include <cstdio> # include <cstring> # include <algorithm> # include <cmath> #define LL long long #define pi 2 *asin( 1.0 ) using namespace std; int n; LL a[ 10010 ]; int judge(LL x) { int cnt= 0 ; for ( int i= 0 ;i<n;i++) { cnt+= int ( 1.0 *pi*a[i]*a[i]/x); } return cnt; } LL binary_find( int m,LL up) { up=(LL)( 1.0 *pi*up*up); LL low= 0 ; while (low<=up) { LL mid=(low+up)/ 2 ; int temp=judge(mid); //if(temp>=m) return mid;这里不能返回,因为不一定数量相等时最大,精度问题,同一个temp对应对个mid~!! if (temp>=m) low=mid+ 1 ; else up=mid- 1 ; } return low; } int main() { int t,m; scanf( "%d" ,&t); while (t--) { scanf( "%d%d" ,&n,&m); LL maxn= 0 ; for ( int i= 0 ;i<n;i++) { scanf( "%lld" ,&a[i]); a[i]=a[i]* 1000 ; maxn=max(maxn,a[i]); } printf( "%.4lf\n" ,( 1.0 *(binary_find(m+ 1 ,maxn))/ 1000000 )); } return 0 ; }
|