题目:将N个饼分成F+1份,问分的最大体积。 0-max(饼的体积),采用二分,寻找分成F+1份的最大体积,f(x)>=F+1  left=mid;(而不是mid+1(wrong answer)).

精度的二分,采用的边界是开区间 (left,right),

题目来源: http://acm.hdu.edu.cn/showproblem.php?pid=1969

 

关于二分边界,请看 ----  http://blog.csdn.net/sunmenggmail/article/details/7540970

 

边界错误造成的问题
二分查找算法的边界,一般来说分两种情况,一种是左闭右开区间,类似于[left, right),一种是左闭右闭区间,类似于[left, right].需要注意的是, 循环体外的初始化条件,与循环体内的迭代步骤, 都必须遵守一致的区间规则,也就是说,如果循环体初始化时,是以左闭右开区间为边界的,那么循环体内部的迭代也应该如此.如果两者不一致,会造成程序的错误(有时是找不到元素甚至是死循环).

 

int search(int array[], int n, int v)
{
    
int left, right, middle;

    left 
= 0, right = n - 1;    //初始化区间分界

    
while (left <= right)
    {
        middle 
= (left + right) / 2;
        
if (array[middle] > v)
        {
            right 
= middle;              //循环体内迭代边界,
        }
        
else if (array[middle] < v)
        {
            left 
= middle;                             //循环体内迭代边界
        }
        
else
        {
            
return middle;
        }
    }

    
return -1;
}

 

1:初始化区间

【】左闭右闭   l=0,r=n-1;

循环迭代  

array[middle] > v  v应该在[left,middle-1]   right=mid-1;

array[middle]<v  v应该在[middle+1,right]  left=middle+1;

2:初始化 ()左开右开  l=-1,r=n;

循环迭代边界

array[middle]>v v应该在(left,middle)  right=middle;

array[middle]<v  v应该在(middle,right)  left=middle;

3:初始化左闭右开  [ ),l=0,r=n;

循环迭代

array[middle]>v  v应该在[left,middle) right=middle;

array[middle]<v  v应该在[middle+1,right), left=middle+1;

4:初始化左开右闭 ( ] l=-1,r=n-1;

循环迭代

array[middle]>v v应该在(l,middle-1]  right=middle-1;

array[middle]<v v应该在(middle,r] left=middle;

 

 1 #include<iostream>
 2 #include<stdio.h>
 3 #include<string>
 4 #include<string.h>
 5 #include<algorithm>
 6 #include<math.h>
 7 #define eps 1e-7
 8 #define PI acos(-1.0)
 9 using namespace std;
10 double pie[10011];
11 int N;
12 double Bi_Search(double left,double right,int b)
13 {
14     double mid;
15     while(right-left>=eps)
16     {
17         mid=(right+left)/2;
18         int sum=0;
19         for(int i=0;i<N;i++)
20         {
21             sum+=int(pie[i]/mid);
22         }
23         if(sum>=b)
24         {
25             left=mid;
26         }
27         else
28             right=mid;
29 
30     }
31     return (right+left)/2;
32 }
33 int main()
34 {
35     int t,ri;
36     int F;
37     double left,right;
38     cin>>t;
39     while(t--)
40     {
41         left=0,right=0;
42         cin>>N>>F;
43 
44         for(int i=0;i<N;i++)
45         {
46             cin>>ri;
47             pie[i]=PI*ri*ri;
48             right=right>pie[i]?right:pie[i];
49         }
50         printf("%.4f\n",Bi_Search(left,right,F+1));
51 
52     }
53     return 0 ;
54 }