映射
二分查找《——f[x]:数组<------> f(x):函数——》二分答案
存储资源 计算资源
互换
空间 <------> 时间
二分算法在函数中的应用条件
1.f数组有序,f函数为单调函数
2.f[x] = y, y --> x难, x-->y 易;
1.查找第一个1 == 查找第一个大于target的数 ;
初始条件:head = 0, tail =
arr.size() ;//二分查找的范围要包括所有可能的目标值
while(head < tail)
0(target >= arr[mid]):head = mid + 1;
1(target < arr[mid]): tail = mid;
边界条件:无需特判,全部为0的情况已在内。
2.查找最后一个1 == 查找最后一个大于target的数
初始条件:head = 0,
tail = size() - 1;//二分查找的范围要包括所有可能的目标值
while(head < tail)
1(target <= arr[mid]):head = mid;
0(target > arr[mid]): tail = mid - 1;
边界条件:当head == tail + 1;
则mid = (head + tail) / 2 == head;
所以,mid = (head + tail) >> 1 不可用
要用mid = (head + tail + 1) >> 1
代码演示:
#include
<iostream>
#include
<cstdio>
#include
<cstdlib>
using
namespace
std;
//打印被查找的数组
void
output(
int
*
arr
,
int
n
,
int
ind
= -1) {
int
len = 0;
for
(
int
i = 0; i <
n
; i++) {
//存入打印的字符个数
len += printf(
"%4d"
, i);
}
printf(
"\n"
);
for
(
int
i = 0; i < len; i++) printf(
"-"
);
printf(
"\n"
);
for
(
int
i = 0; i <
n
; i++) {
//改变目标元素的颜色
if
(i ==
ind
) printf(
"\033[1;32m"
);
printf(
"%4d"
,
arr
[i]);
if
(i ==
ind
) printf(
"\033[0m"
);
}
printf(
"\n"
);
return
;
}
//二分查找
int
binary_search(
int
*
arr
,
int
n
,
int
x
) {
int
head = 0, tail =
n
- 1, mid;
while
(head <= tail) {
mid = (head + tail) / 2;
printf(
"[%d, %d], mid = %d, arr[%d] = %d\n"
,
head, tail, mid,
mid,
arr
[mid]
);
if
(
arr
[mid] ==
x
)
return
mid;
if
(
arr
[mid] <
x
) head = mid + 1;
else
tail = mid - 1;
}
return
-1;
}
//二分答案
#define
EXP
1e-4
#define
min
(a, b) ((a) < (b) ? (a) : (b))
//函数 ---> 另类的数组
// x相当于下标,f(x)相当于下标指向的值
double
f(
double
x
) {
if
(
x
>= 0)
x
-=
min
(
x
, 3000) * 0.03;
if
(
x
> 3000)
x
-= (
min
(
x
, 12000) - 3000) * 0.1;
if
(
x
> 12000)
x
-= (
min
(
x
, 25000) - 12000) * 0.2;
if
(
x
> 25000)
x
-= (
min
(
x
, 35000) - 25000) * 0.25;
if
(
x
> 35000)
x
-= (
min
(
x
, 55000) - 35000) * 0.3;
if
(
x
> 55000)
x
-= (
min
(
x
, 80000) - 55000) * 0.35;
if
(
x
> 80000)
x
-= (
x
- 80000) * 0.45;
return
x
;
}
double
bineary_algorithm(
double
y
) {
double
head = 0, tail = 1000000, mid;
//精度限制
while
(tail - head >=
EXP
) {
mid = (head + tail) / 2.0;
printf(
"[%lf, %lf], mid = %lf, arr[%lf] = %lf\n"
,
head, tail, mid,
mid, f(mid)
);
if
(f(mid) <
y
) head = mid;
else
tail = mid;
}
return
head;
}
void
test_binary_search(
int
n
) {
int
*arr = (
int
*)malloc(
sizeof
(
int
) *
n
);
arr[0] = rand() % 10;
for
(
int
i = 1; i <
n
; i++) arr[i] = arr[i - 1] + rand() % 10;
output(arr,
n
);
int
x;
while
(~scanf(
"%d"
, &x)) {
if
(x == -1)
break
;
int
ind = binary_search(arr,
n
, x);
output(arr,
n
, ind);
}
free(arr);
return
;
}
void
test_binary_algorithm() {
printf(
"\ntest binary algorithm\n"
);
double
y;
while
(~scanf(
"%lf"
, &y)) {
if
(y < 0)
break
;
double
x = bineary_algorithm(y);
printf(
"f(%.2lf) = %.2lf\n"
, x, y);
}
return
;
}
int
main() {
#define
MAX_N
10
test_binary_search(
MAX_N
);
test_binary_algorithm();
return
0;
}