二分法查找,也称为折半法,是一种在有序数组中查找特定元素的搜索算法。
二分法查找的思路如下:
(1)首先,从数组的中间元素开始搜索,如果该元素正好是目标元素,则搜索过程结束,否则执行下一步。
(2)如果目标元素大于/小于中间元素,则在数组大于/小于中间元素的那一半区域查找,然后重复步骤(1)的操作。
(3)如果某一步数组为空,则表示找不到目标元素。
二分法查找的时间复杂度O(logn)。
首先对一个简单的数组进行实验一下 找到指定的key
#include <iostream>
#include <algorithm>
using namespace std;
int arr[10]={1,5,6,3,2,8,9,7,4,10};
int binary_search (int star, int end, int key)
{
int ret = -1;//未搜索到数据返回数据-1下标
int mid;
while(star<=end){
mid=(star+end)/2;
if(arr[mid]<key)
star = mid+1;
else if(arr[mid]>key)
end = mid -1;
else {
ret = mid;
break;
}
}
return ret;//单一出口;
}
int main()
{
sort(arr,arr+10);
int result = binary_search(0,10,5);
cout<<"要找的数据的下标为: "<<result<<endl;
return 0;
}
首先必须确保你要查找的数据是单调的,如果不是单调的需要进行排序,这里用了sort排序,前面博客已经介绍过,这里不在阐述 sort排序
接下来就说一说这道体现二分基础的简单题
题目链接 Pie–hdu1969(二分法)
题解:
给你n个蛋糕的半径,你有m个朋友,所以总共有m+1个人,现在要分蛋糕,要求每个人分到的大小都是一样的,且每个人的蛋糕都是从一块上切割下来的(不能是2个不同的蛋糕拼起来的),现在问每个人最多能分到多少蛋糕(体积),保留到小数点后4位输出。
AC代码:
#include<bits/stdc++.h> //偷偷用了万能头文件 嘘......
using namespace std;
typedef long long int ll;
const int MAX=1e7+100;
double pi = acos(-1.0); // //计算π的值,这样更精确
int n,m;
int i,j;
double maxx,maxv,r;
double s[10000];
bool check(double x) //判断此时的mid(也就是每个人的蛋糕面积)是否满足条件
{
int num=0;
for(i=0;i<n;i++)
{
num+=int(s[i]/x); //计算有多少块蛋糕大于此时的平均面积
}
if(num>=m)
return 1; //如果有这么多块面积分给所有人,则满足题意
else
return 0;
}
int main()
{
int t;
while(cin >>t)
{
while(t--)
{
maxx,maxv=0.0; // 分别代表蛋糕总面积和每个人无条件下分到的最大的蛋糕
cin >>n>>m;
m+=1; //不要忘记自己哟
memset(s,0,sizeof(s));
for(i=0;i<n;i++)
{
cin >>r;
s[i]=r*r*pi; //记录所有蛋糕的面积
maxv+=s[i]; //先把蛋糕的面积总和求出来
}
maxx=maxv/m; //每个人平均分到的最大蛋糕就是蛋糕总面积的平均值
double mid,left=0.0,right=maxx;//面积从0到平均值二分
while(right-left>1e-7) //满足这个精度则跳出循环(不了解精度问题,模仿别人的写法)
{
mid=(left+right)/2; //二分取中
if(check(mid)) //如果此时的mid满足条件,则证明mid还可以取得大一点,则取后半段继续搜
left=mid;
else
right=mid; //若不满足,则蛋糕取大了,则取前半段继续搜
}
printf("%.4f\n",mid);
}
}
return 0;
}
今天的博客就到此结束,刚开始已经写了一半了,电脑发热关机了 我***。不过还好 又写了一遍,继续。go again…