BZOJ 1007: [HNOI2008]水平可见直线 (半平面交)
eps害人啊…我开到1e-10都不够,1e-12才够.
然鹅我看有的代码不用写eps都过了…
蒟蒻被动:被卡精度.
#include <bits/stdc++.h>
using namespace std;
const double eps = 1e-12;
const int MAXN = 50005;
inline double sqr(double x) { return x*x; }
inline double dcmp(double x) {
if(x < -eps) return -1;
if(x > eps) return 1;
return 0;
}
struct Point {
double x, y;
Point(){}
Point(const double &x, const double &y):x(x), y(y){}
inline Point operator +(const Point &o)const { return Point(x + o.x, y + o.y); }
inline Point operator -(const Point &o)const { return Point(x - o.x, y - o.y); }
inline Point operator *(const double &k)const { return Point(x * k, y * k); }
inline double operator *(const Point &o)const { return x * o.y - y * o.x; }
inline friend double dist(const Point &A, const Point &B) { return sqrt(sqr(A.x-B.x) + sqr(A.y-B.y)); }
};
struct Line {
Point p, v; int id; double angle;
Line(){}
Line(const Point &p, const Point &v):p(p), v(v){
angle = atan2(v.y, v.x);
}
inline friend bool On_Right(const Line &l, const Point &p) {
return dcmp(l.v * (p - l.p)) <= 0;
}
inline bool operator <(const Line &o)const {
if(!dcmp(angle-o.angle))
return dcmp(v * (o.p - p)) < 0;
return angle < o.angle;
}
inline friend Point Get_Intersection(const Line &l1, const Line &l2) {
Point u = l1.p - l2.p;
double k = (l2.v * u) / (l1.v * l2.v);
return l1.p + l1.v * k;
}
}arr[MAXN], q[MAXN]; int top;
inline void Insert(const Line &l) {
while(top > 1 && On_Right(l, Get_Intersection(q[top-1], q[top]))) --top;
q[++top] = l;
}
int n, tot; bool vis[MAXN];
int main() {
scanf("%d", &n);
for(int i = 1; i <= n; ++i) {
double k, b;
scanf("%lf%lf", &k, &b);
arr[++tot] = Line(Point(0, b), Point(1, k));
arr[tot].id = i;
}
sort(arr + 1, arr + tot + 1);
q[++top] = arr[1];
for(int i = 2; i <= tot; ++i)
if(dcmp(arr[i].angle-arr[i-1].angle))
Insert(arr[i]);
for(int i = 1; i <= top; ++i) vis[q[i].id] = 1;
for(int i = 1; i <= n; ++i)
if(vis[i]) printf("%d ", i);
}