题目:将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 }