整数二分:
二分的本质并不是单调性,而是从一半满足一半不满足的区间中找到边界点。
模板题:
数的范围
给定一个按照升序排列的长度为n的整数数组,以及q个查询。
对于每个查询,返回一个元素k的起始位置和终止位置(位置从0开始计数)。
如果数组中不存在该元素,则返回 -1 -1
。
输入格式
第一行包含整数n和q,表示数组长度和询问个数。
第二行包含n个整数(均在1~10000范围内),表示完整数组。
接下来q行,每行包含一个整数k,表示一个询问元素。
输出格式
共q行,每行包含两个整数,表示所求元素的起始位置和终止位置。
如果数组中不存在该元素,则返回 -1 -1
。
数据范围
1 <= n <= 100000
1 <= q <= 10000
1 <= k <= 10000
输入样例:
6 3
1 2 2 3 3 4
3
4
5
输出样例:
3 4
5 5
-1 -1
代码模版:
1 #include <iostream>
2
3 using namespace std;
4
5 const int N = 1e5 + 10;
6
7 int n, m;
8 int q[N];
9
10 int main()
11 {
12 scanf("%d%d", &n, &m);
13 for (int i = 0; i < n; i++) scanf("%d", &q[i]);
14
15 while (m--)
16 {
17 int x;
18 scanf("%d", &x);
19
20 int l = 0, r = n - 1;
21 while (l < r)
22 {
23 int mid = l + r >> 1;
24 if (q[mid] >= x) r = mid;
25 else l = mid + 1;
26 }
27
28 if (q[l] != x) cout << "-1 -1" << endl;
29 else
30 {
31 cout << l << ' ';
32
33 int l = 0, r = n - 1;
34 while (l < r)
35 {
36 int mid = l + r + 1 >> 1;
37 if (q[mid] <= x) l = mid;
38 else r = mid - 1;
39 }
40
41 cout << l << endl;
42 }
43 }
44
45 return 0;
46 }
View Code
浮点数二分:
模板题:
数的三次方根
给定一个浮点数n,求它的三次方根。
输入格式
共一行,包含一个浮点数n。
输出格式
共一行,包含一个浮点数,表示问题的解。
注意,结果保留6位小数。
数据范围
-10000 <= n <= 10000
输入样例:
1000.00
输出样例:
10.000000
代码模版:
1 #include <iostream>
2
3 using namespace std;
4
5 int main()
6 {
7 double x;
8 cin >> x;
9
10 double l = -10000, r = 10000;
11 while (r - l > 1e-8)
12 {
13 double mid = (l + r) / 2;
14 if (mid * mid * mid >= x) r = mid;
15 else l = mid;
16 }
17
18 printf("%lf\n", l);
19
20 return 0;
21 }
View Code