【题目链接】
【思路要点】
- 补档博客,无题解。
【代码】
#include<bits/stdc++.h> using namespace std; #define MAXN 300005 #define INF 1e15 #define EPS 1e-18 #define QPS 1e-15 #define LPS 1e-13 #define PI acos(-1) struct point {long double x, y; }; struct line {point a, b; long 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, long double b) {return (point) {a.x * b, a.y * b}; } long double operator * (point a, point b) {return a.x * b.y - a.y * b.x; } long double Polar_Angle(point a) {return atan2(a.y, a.x); } bool equal(long double a, long double b) {return fabs(a - b) < EPS; } point intersect(line x, line y) { long double u = (x.a - x.b) * (y.a - x.b); long double v = (x.b - x.a) * (y.b - x.b); return (y.a * v + y.b * u) * (1 / (u + v)); } int n; long double x[MAXN], yI[MAXN], yII[MAXN]; line a[MAXN]; point getpoint(long double x, long double y, long double z) { long double ty = y / x - z * x; return (point) {z, ty}; } bool cmp(line x, line y) { return x.k < y.k; } bool onright(line x, point y) { return (x.b - x.a) * (y - x.a) < EPS; } bool check(int n) { int cnt = 0; cnt++; a[cnt].a = (point) {-INF, INF}; a[cnt].b = (point) {-INF, LPS}; a[cnt].k = Polar_Angle(a[cnt].b - a[cnt].a); cnt++; a[cnt].a = (point) {-INF, LPS}; a[cnt].b = (point) {-LPS, LPS}; a[cnt].k = Polar_Angle(a[cnt].b - a[cnt].a); cnt++; a[cnt].a = (point) {-LPS, LPS}; a[cnt].b = (point) {-LPS, INF}; a[cnt].k = Polar_Angle(a[cnt].b - a[cnt].a); cnt++; a[cnt].a = (point) {-LPS, INF}; a[cnt].b = (point) {-INF, INF}; a[cnt].k = Polar_Angle(a[cnt].b - a[cnt].a); for (int i = 1; i <= n; i++) { cnt++; a[cnt].a = getpoint(x[i], yI[i], 0); a[cnt].b = getpoint(x[i], yI[i], 1); a[cnt].k = Polar_Angle(a[cnt].b - a[cnt].a); cnt++; a[cnt].a = getpoint(x[i], yII[i], 1); a[cnt].b = getpoint(x[i], yII[i], 0); a[cnt].k = Polar_Angle(a[cnt].b - a[cnt].a); } sort(a + 1, a + cnt + 1, cmp); static line q[MAXN]; static point p[MAXN]; int l = 1, r = 1; q[1] = a[1]; for (int i = 2; i <= cnt; i++) { while (l < r && onright(a[i], p[r - 1])) r--; while (l < r && onright(a[i], p[l])) l++; q[++r] = a[i]; if (equal(0, (q[r].b - q[r].a) * (q[r - 1].b - q[r - 1].a))) { r--; if ((q[r].b - q[r].a) * (a[i].b - q[r].a) > 0) q[r] = a[i]; } if (r > l) p[r - 1] = intersect(q[r - 1], q[r]); if (q[r].k - q[r - 1].k >= PI) return false; } while (l < r && onright(q[l], p[r - 1])) r--; while (l < r && onright(q[r], p[l])) l++; return r - l >= 2; } int main() { scanf("%d", &n); for (int i = 1; i <= n; i++) { scanf("%Lf%Lf%Lf", &x[i], &yI[i], &yII[i]); yI[i] -= QPS; yII[i] += QPS; } int l = 1, r = n; while (l < r) { int mid = (l + r + 1) / 2; if (check(mid)) l = mid; else r = mid - 1; } cout << l << endl; return 0; }