二分搜索
二分搜索其实就是折半查找或者说折半查找的灵活应用。折半的算法过程如下(为表达方便,过程并没有严格的按照语法写):
1 /*
2 在有序表中ST(假定为升序)中查找关键字为key的元素,
3 若查到返回元素在表中的位置,否则返回0
4 l,h分别为有序表的上下限
5 */
6 int search(ST,key)
7 {
8 low=l,high=h;//置查找区间
9 while(low<high)
10 {
11 mid=(l+high)/2;
12 if(ST[mid]==key)//找到返回
13 return mid;
14 else if(key<ST[mid])//在前半部分继续查找
15 high=mid-1;
16 else //在后半部分查找
17 low=mid+1;
18 }
19 return 0;
20 }
题目大意:给你n个蛋糕的半径,有f个朋友,将他们分成包括分割者在内的f+1块,每块的大小相等,且每块为一整块,不能由多块小的拼凑而成,输出每小块的最大面积
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /*
2 二分法
3 */
4 #include <iostream>
5 #include <stdio.h>
6 #include <string.h>
7 #include <math.h>
8 using namespace std;
9 const double pi=acos(-1.0);
10 //用函数求精度更高,double型数据只能保证15位有效数字,float是6位
11 double s[10005];
12 double mianji(int r)
13 {
14 return pi*r*r;
15 }
16 int main()
17 {
18 int r,t,f,n;
19 int num;
20 //printf("%.15lf\n",acos(-1.0));
21 while(scanf("%d",&t)!=EOF)
22 {
23
24 while(t--)
25 {
26 double l=0,h=0,m;
27 double ans=0;
28 scanf("%d%d",&n,&f);
29 f+=1;//包括他本人
30 for(int i=0;i<n;i++)
31 {
32 scanf("%d",&r);
33 s[i]=mianji(r);
34 h+=s[i];
35 }
36 h=h/f;//蛋糕的均值,二分法蛋糕面积的上限
37 while(h-l>1e-7)//注意精度
38 {
39 m=(l+h)/2;
40 num=0;
41 for(int i=0;i<n;i++)
42 {
43 num+=int(s[i]/m);
44 }
45 if(num<f)
46 {
47 h=m;
48 continue;
49 }
50 if(num>=f)
51 {
52 l=m;
53 continue;
54 }
55 }
56 printf("%.4lf\n",m);
57 }
58 }
59 return 0;
60 }
hdu2199 Can you solve this equation?
给你一个函数 8*x^4 + 7*x^3 + 2*x^2 + 3*x + 6 == Y 对于每一个y,求出x的值(0<=x<=100,fabs(y<=1e10))
题目大意:这道题就是给你一个圆台,里面装了一些水,现在告诉你圆台上下底半径,高度,水的体积,问你水的高度是多少。
这道题可以二分搜索也可以计算几何,现在是二分的算法
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream>
2 #include <stdio.h>
3 #include <math.h>
4 using namespace std;
5 const double pi=acos(-1.0);
6 //求圆台的体积
7 double get_area(double r,double R,double h,double H)
8 {
9 double rr=h*(R-r)/H+r;
10 return (rr*rr+rr*r+r*r)*h*pi/3;//圆台体积公式
11 }
12 int main()
13 {
14 int t;
15 double r,R,H,v;
16 cin>>t;
17 while(t--)
18 {
19 cin>>r>>R>>H>>v;
20 double mid=0;
21 double l=0,h=H;
22 double area;
23 while(l<h)//二分搜索水的高,最高为圆台高H
24 {
25 mid=(l+h)/2;
26 area=get_area(r,R,mid,H);
27 if(area<v-1e-7)
28 {
29 l=mid;
30 continue;
31 }
32 if(area>v+1e-7)
33 {
34 h=mid;
35 continue;
36 }
37 break;
38 }
39 printf("%.6lf\n",mid);
40 }
41 return 0;
42 }