intmain(){ scanf("%d %d",&n,&m); for (int i = 0;i < n;i++) scanf("%d",&q[i]); int x; while (m--){ scanf("%d",&x); int l = 0,r = n-1; while (l < r){// 先二分查找x的起始位置 int mid = l + r >> 1; if (q[mid] >= x) r = mid; else l = mid + 1; } if (q[l] != x) puts("-1 -1"); else{ printf("%d ",l); int l = 0,r = n-1; while (l < r){// 再二分查找x的终止位置 int mid = l + r + 1 >> 1;// l = mid补上+1上取整 if (q[mid] <= x) l = mid; else r = mid - 1; } printf("%d\n",l); } } return0; }
1.3.2:浮点数二分
浮点数二分不需要考虑复杂的边界问题。
例题:acwing.7890. 数的三次方根(模板题)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
给定一个浮点数 n,求它的三次方根。
输入格式 共一行,包含一个浮点数 n。
输出格式 共一行,包含一个浮点数,表示问题的解。 注意,结果保留 6 位小数。
数据范围 −10000≤n≤10000 输入样例: 1000.00 输出样例: 10.000000
y总代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
#include<cstdio> usingnamespacestd;
intmain(){ double n; scanf("%lf",&n); double l = -100,r = 100;// 算平方根左边界取0,立方根左边界取-100 // 注意:1e-8这里换成int就TLE了!!!必须定义为double while (r - l > 1e-8){// 经验值,比要求的1e-6多开2位 double mid = (l+r) / 2; if (mid*mid*mid >= n) r = mid; else l = mid; } printf("%lf",l);// 默认输出6位小数 return0; }
// C = A + B,A和B都是正整数 vector<int> add(vector<int> &A,vector<int> &B){ vector<int> C; int t = 0; for (int i = 0;i < A.size() || i < B.size();i++){ if (i < A.size()) t += A[i]; if (i < B.size()) t += B[i]; C.push_back(t % 10); t /= 10;// 进位到下一位 } if (t) C.push_back(1);// 判断最高位是否需要进位 // 这里可以参考笔记(三)中高精度乘法对最高位进位的处理方式,在for语句中判断 || t,就能省略循环外判断 // 题目已经说明不含前导零否则要处理! return C; }
intmain(){ string a,b; vector<int> A,B;
cin >> a >> b; for (int i = a.size()-1;i >= 0;i--) A.push_back(a[i] - '0'); for (int i = b.size()-1;i >= 0;i--) B.push_back(b[i] - '0');
auto C = add(A,B); for (int i = C.size()-1;i >= 0;i--) printf("%d",C[i]); return0; }