#include<iostream> #include<algorithm> usingnamespace std; int a[200005]; intmain() { int n, x; cin >> n >> x; for (int i = 1; i <= n; i++) cin >> a[i]; int z = 1, y = n; //核心代码 while (z <= y) { //这里其实mid = (z + y) / 2,而下面的写法是为了防止有时候爆int int mid = z + (y - z) / 2; //下面两个条件判断,哪个不取等,就输出哪个 if (a[mid] >= x) y = mid - 1; else z = mid + 1; } cout << z; //cout << y + 1; return0; }
二.找出最后一个小于等于 x 的元素这里只展示核心代码,与一进行比较
1 2 3 4 5 6 7 8 9 10 11
int z = 1, y = n; //核心代码 while (z <= y) { //这里其实mid = (z + y) / 2,而下面的写法是为了防止有时候爆int int mid = z + (y - z) / 2; //下面两个条件判断,哪个不取等,就输出哪个 if (a[mid] <= x) z = mid + 1; else y = mid - 1; } cout << y; //cout << z - 1;
简单记忆区分两种情况在于先判断哪种情况
二分(STL)
binary_search 返回 bool 值, 是否存在
lower_bound 返回第一个大于等于 x 元素的地址
upper_bound 返回第一个大于 x 的元素的地址
这三个的参数(a, a + n, x)
答案检验法
一种使用二分思想的方法,给出答案可能的最小值 z ,最大值 y,然后对答案进行二分,假设每次二分的结果就是最后的正确答案,然后循环内部进行 judge 函数判断是否满足,从而进行不同的左右区间缩减。最终找到真正的正确答案。
#include<iostream> #include<algorithm> usingnamespace std; double y = 0; int n, k; structty { double w, v; double m; }a[500010]; boolcmp(ty a, ty b) { return a.m > b.m; } booljudge(double x) { for (int i = 1; i <= n; i++) a[i].m = a[i].v - a[i].w * x; sort(a + 1, a + 1 + n, cmp); double sum = 0; for (int i = 1; i <= k; i++) sum += a[i].m; if (sum >= 0) return1; return0; } intmain() { cin >> n >> k; for (int i = 1; i <= n; i++) { cin >> a[i].w >> a[i].v; y += a[i].w; } double z = 0; int t = 100; while (t--) { double mid = (z + y) / 2; if (judge(mid)) z = mid; else y = mid; } printf("%.9lf", (z + y) / 2); return0; }