bzoj 1007 水平可見直線 半平面交稀裡糊塗的過了...
阿新 • • 發佈:2018-12-06
題意:按y=Ax+B的形式給出n(<=50000)條直線,求從y值為無窮大的地方向下看能看到的直線編號
一看到題目就想到半平面交,以每條直線的上方為一個半平面,求半平面的交,交集中存在的直線就是能看到的直線
但是寫出來之後發現樣例都過不了。。。
對於樣例,如果允許半平面在邊界處重疊那麼答案是1,2,3,如果不允許只有1。。
然後抱著試一試的心理交上去了,結果竟然直接AC了。。
後來看題解只需要考慮交點x座標。。
c++ code 蒟蒻532ms ORZ前排0msAC的神犇。。。。
/************************************************************** Problem: 1007 User: Lytning Language: C++ Result: Accepted Time:532 ms Memory:8524 kb ****************************************************************/ #include <iostream> #include <cstdio> #include <cstdlib> #include <algorithm> #include <cstring> #include <cmath> using namespace std; const double eps = 1e-8; int dcmp(double x) { if(fabs(x) < eps) return 0; else return x>0? 1 : -1; } #define Vector Point struct Point { double x,y; Point(double x=0, double y=0):x(x),y(y) {} }; Vector operator + (Vector A, Vector B) {return Vector(A.x + B.x, A.y + B.y);} Vector operator - (Vector A, Vector B) {return Vector(A.x - B.x, A.y - B.y);} Vector operator * (Vector A, double p) {return Vector(A.x * p, A.y * p);} Vector operator / (Vector A, double p) {return Vector(A.x / p, A.y / p);} bool operator == (const Vector& A, const Vector& B) {return dcmp(A.x - B.x)==0 && dcmp(A.y - B.y)==0;} double Cross(Vector A, Vector B) { return A.x * B.y - A.y * B.x; } struct Line { Point P; Vector v; double ang; int num; Line() {} Line(int A, int B, int nums)//y=Ax+B { double x = 1.0, y = A*x+B; P = Point(x,y); x = 2.0, y = A*x+B; v = Point(x,y) - P; ang = atan2(v.y, v.x); num = nums; } bool operator < (const Line& L) const { return ang < L.ang; } }Li[50000+5];; bool onLeft(Line L, Point P) { return Cross(L.v,P-L.P) > 0; } inline Point GetIntersection(Line a, Line b) { Vector u = a.P - b.P; double t = Cross(b.v, u) / Cross(a.v, b.v); return a.P + a.v * t; } bool cmp_num(Line a, Line b) { return a.num < b.num; } void HalfplaneIntersection(Line* L, int n) { sort(L,L+n); Point *p = new Point[n]; Line *q = new Line[n]; int first, last; q[first = last = 0] = L[0]; for(int i=1; i<n; i++) { while(first < last && !onLeft(L[i], p[last-1])) last--; while(first < last && !onLeft(L[i], p[first])) first++; q[++last] = L[i]; if(q[last].v == q[last-1].v) { last --; if(onLeft(q[last], L[i].P)) q[last] = L[i]; } if(first < last) p[last-1] = GetIntersection(q[last-1],q[last]); } while(first < last && !onLeft(q[first],p[last-1])) last--; Line *lines = new Line[n]; int k = 0; for(int i = first; i<=last; i++) lines[k++] = q[i]; sort(lines,lines+k,cmp_num); for(int i = 0; i < k; i++) cout<<lines[i].num<<" "; } int main() { //freopen("bz1007.in","r",stdin);freopen("bz1007.out","w",stdout); int n; cin>>n; for(int i = 1; i <= n; i++) { int A,B; cin>>A>>B; Li[i-1] = Line(A,B,i); } HalfplaneIntersection(Li,n); }