Day2 ---二分
这里直接给出模板
两种对应不同的情况 可以借助数轴理解
int bsearch_1(int l, int r) { while (l < r) { int mid = l + r >> 1; if (check(mid)) r = mid; else l = mid + 1; } return l; } int bsearch_2(int l, int r) { while (l < r) { int mid = l + r + 1 >> 1; if (check(mid)) l = mid; else r = mid - 1; } return l; }
补充:有时候可以借助STL的std::lower_bound()来找第一个大于等于你的值的数,std::upper_bound()来找第一个大于数所在的位置
P1873 砍树
int a[1000005]; int n, m; bool check(int k) { //检查可行性,k为锯片高度 long long sum = 0; for (int i = 1; i <= n; i++) //检查每一棵树 if (a[i] > k) //如果树高于锯片高度 sum += (long long)(a[i] - k); //累加树木长度 return sum >= m; //如果满足最少长度代表可行 } int find(int x) { int l = 1, r = 1000000001; //因为是左闭右开的,所以10亿要加1 while (l + 1 < r) { //如果两点不相邻 int mid = (l + r) / 2; //取中间值 if (check(mid)) //如果可行 l = mid; //升高锯片高度 else r = mid; //否则降低锯片高度 } return l; //返回左边值 } int main() { cin >> n >> m; for (int i = 1; i <= n; i++) cin >> a[i]; cout << find(m); return 0; }
实数二分 Pie http://poj.org/problem?id=3122
#include<iostream> #include<string> #include<cmath> #include<cstring> #include<vector> #include<map> #include<set> #include<algorithm> #include<queue> #include<stack> #include<sstream> #include<cstdio> const double eps = 1e-7; const int maxn = 1e6 + 5; const double PI = acos(-1.0); typedef long long ll; using namespace std; double r[10004]; int n, k; bool check(double x) { int cnt = 0; for (int i = 0; i < n; i++) { cnt+= (int)(r[i] / x); } if (cnt >= k+1) return true; else return false; } int main() { std::ios::sync_with_stdio(0); cin.tie(0); double Max; int T; cin >> T; while (T--) { cin >> n >> k; Max = -1; for (int i = 0; i < n; i++) { cin >> r[i]; r[i]=r[i]*r[i]*PI; Max = max(Max, r[i]); } double l = 0; double r = Max+5; while (r - l > eps) { double mid = (l + r) / 2; if (check(mid)) { l = mid; } else r = mid; } printf("%.4f\n", l ); } return 0; }
注意精度
三分
主要用于求函数极值
double f(double a){/*根据题目意思计算*/} double three(double l,double r) //找凸点 { while(l<r-eps) { double mid=(l+r)/2; double mmid=(mid+r)/2; if(f(mid)>f(mmid)) r=mmid; else l=mid; } if(f(l)>f(r)) return l; else return r; }
秦九韶算法从里到外逐层计算一次多项式
double F(double x) { double sum = 0; for (int i = n; i >= 0; i--) { sum = sum * x + a[i]; } return sum; }