【题目链接】
【思路要点】
- 半平面交求出可行的区域(是一个凸型区域)。
- 最优解只可能在\(x_{i}\)或凸型区域的顶点处取到,依次检查即可。
- 时间复杂度\(O(NLogN)\)或\(O(N^2)\)。
【代码】
#include<bits/stdc++.h> using namespace std; #define MAXN 5005 #define INF 1e18 #define EPS 1e-9 struct point {double x, y; }; struct line {point a, b; double k; }; point operator + (point a, point b) {return (point) {a.x + b.x, a.y + b.y}; } point operator - (point a, point b) {return (point) {a.x - b.x, a.y - b.y}; } point operator * (point a, double b) {return (point) {a.x * b, a.y * b}; } double operator * (point a, point b) {return a.x * b.y - a.y * b.x; } bool equal(double x, double y) {return fabs(x - y) <= EPS; } double Polar_Angle(point a) {return atan2(a.y, a.x); } point intersect(line x, line y) { double u = (x.b - x.a) * (y.a - x.a); double v = (x.a - x.b) * (y.b - x.a); return (y.a * v + y.b * u) * (1 / (u + v)); } bool cmp(line x, line y) { if (equal(x.k, y.k)) return (x.b - x.a) * (y.b - x.a) < 0; else return x.k < y.k; } bool func(line x, line y, line z) { point tmp = intersect(x, y); return (z.b - z.a) * (tmp - z.a) < 0; } point p[MAXN], b[MAXN]; line a[MAXN], q[MAXN]; int l, r, n; point get(point a, point b, double x) { point v = b - a; double rate = (x - a.x) / (b.x - a.x); return a + v * rate; } double queryp(double x) { for (int i = 1; i < n; i++) if (x >= p[i].x && x <= p[i + 1].x) return get(p[i], p[i + 1], x).y; } double queryq(double x) { double ans = -INF; for (int i = l; i <= r; i++) ans = max(ans, get(q[i].a, q[i].b, x).y); return ans; } int main() { cin >> n; if (n <= 2) { printf("0.000\n"); return 0; } for (int i = 1; i <= n; i++) cin >> p[i].x; for (int i = 1; i <= n; i++) cin >> p[i].y; for (int i = 1; i < n; i++) { a[i].a = p[i]; a[i].b = p[i + 1]; a[i].k = Polar_Angle(a[i].b - a[i].a); } sort(a + 1, a + n, cmp); l = 1, r = 1; q[1] = a[1]; for (int i = 2; i < n; i++) { if (equal(a[i].k, a[i - 1].k)) continue; while (l < r && func(q[r - 1], q[r], a[i])) r--; q[++r] = a[i]; } double ans = INF; for (int i = l; i < r; i++) b[i] = intersect(q[i], q[i + 1]); for (int i = l; i < r; i++) ans = min(ans, b[i].y - queryp(b[i].x)); for (int i = 1; i <= n; i++) ans = min(ans, queryq(p[i].x) - p[i].y); printf("%.3lf\n", ans + EPS); return 0; }