int类型的二分查找
基本思想:二分查找的基本思想是每次查找缩小查找范围的一半
int LowerBound(int a[], int target, int left, int right)
{
while(right >= left)
{
int mid = left + (right - left) / 2;//防止left + right导致上溢
if(a[mid] > target) right = mid - 1;
else if(a[mid] < target) left = mid + 1;
else if(a[mid] == target) return mid;
}
return -1;
}
为了防止 left + right发生上溢,可换为 left + (right - left) / 2
例题 想找出元素所在数组位置
#include <stdio.h>
int LowerBound(int a[], int target, int left, int right)
{
while(right >= left)
{
int mid = left + (right - left) / 2;//防止left + right导致上溢
if(a[mid] > target) right = mid - 1;
else if(a[mid] < target) left = mid + 1;
else if(a[mid] == target) return mid;
}
return -1;
}
int main(void)
{
int a[105] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int ans;
ans = LowerBound(a, 11, 0, 9);
if(ans >= 0) printf("%d", ans);
else printf("NO");
return 0;
}
double类型二分查找
与int类型类似,唯一不同的是double类型为
while(right - left > 0.0000001)
例题 tz大佬的函数
题目背景
tz大佬从遥远的喜马拉雅山挖出了一个NN阶的函数,为了研究这个神奇的函数,tzdalao把函数拉到了编程俱乐部。
输入格式
第一行,一个正整数N和两个实数ll、rr,表示闭区间范围。
第二行,N+1N+1个实数,从左到右依次表示函数的系数。
输出格式
输出x的值,四舍五入保留5位小数。
样例输入
3 -0.9981 0.5
1 -3 -3 1
样例输出
-0.41421
说明
上述样例n = 3, x3 - 3x2 - 3x + 1
解题思路:讲函数求导后的系数存入数组,用二分法找出一节导数为0的点
AC代码
include <stdio.h>
#include <math.h>
double a[100] = {0}, n, ans1, mid;
double y(double x)//判断一阶导数的大小
{
double j = n-1, ans = 0;
for(int i = 0 ; i < n && j >= 0; i++, j--)
{
ans += a[i]*pow(x, j);
}
return ans;//返回一阶导数的值
}
int main(void)
{
double temp;
double l, r;
scanf("%lf%lf%lf", &n, &l, &r);
temp = n;
for(int i = 0; i <= n; i++)
{
scanf("%lf", &a[i]);
a[i] = a[i]*temp;//求一阶导数的系数
temp -= 1;
}
while(r - l > 0.0000001)。。二分查找
{
mid = (r+l)*1.0/2;
if(y(mid) > 0) l = mid;
else r = mid;
}
printf("%.5lf", mid);
return 0;
}