半平面交模板题。
Time Limit: 6000MS | Memory Limit: 65536K | |
Total Submissions: 6092 | Accepted: 2414 |
Description
Input
Output
Sample Input
3 10000 10000 0 5000 10000 5000 5000 10000 0 5000 5000 0
Sample Output
54166666.7
#include<iostream> #include<cstring> #include<cstdio> #include<cmath> #include<vector> #include<deque> #include<algorithm> using namespace std; const int N=20022;; const double eps=1e-9; const double pi=acos(-1.0); int dcmp(double a){if(abs(a)<eps)return 0;return a>0?1:-1;} #define sig dcmp double sqr(double a){return a*a;} struct point { double x,y; point(){} point(double _x,double _y){x=_x,y=_y;} void input(){scanf("%lf%lf",&x,&y);} double norm(){return sqrt(x*x+y*y);} point rot90(){return point(-y,x);} //double abs(){return hypot(x,y);} bool operator==(point p){return !sig(x-p.x)&&!sig(y-p.y);} bool operator<(point p)const{ if(!sig(y-p.y))return x<p.x; return y<p.y; } }; double dist(point a,point b){return sqrt(sqr(a.x-b.x)+sqr(a.y-b.y));} 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);} point operator*(double b,point a){return point(a.x*b,a.y*b);} point operator/(point a,double b){return point(a.x/b,a.y/b);} double det(point a,point b){return a.x*b.y-a.y*b.x;} #define cross det double dot(point a,point b){return a.x*b.x+a.y*b.y;} struct line { point a,b; line(){} line(point x,point y){a=x,b=y;} }; bool onseg(point p,point s,point t) { return dcmp(det(p-s,t-s))==0&&dcmp(dot(p-s,p-t))<0; } bool parallel(line a,line b) { return dcmp(det(a.a-a.b,b.a-b.b))==0; } point rotate(point p,double a) { double tx=p.x,ty=p.y; return point(tx*cos(a)-ty*sin(a),tx*sin(a)+ty*cos(a)); } point make(line a,line b) { double s1=det(a.a-a.b,b.b-b.a); double s2=det(a.b-b.a,b.b-b.a); point res=(s1*a.b-s2*a.a)/(s1-s2); return res; } #define Half line #define half line double arg(point a) { return atan2(a.y,a.x); } bool ok(point a,Half p) { return dcmp(det(a-p.a,p.b-p.a))<=0; } point crosspoint(Half a,Half b) { double k=det(b.a-b.b,a.a-b.b); k=k/(k-det(b.a-b.b,a.b-b.b)); return a.a+(a.b-a.a)*k; } bool cmp(Half a,half b) { int res=dcmp(arg(a.b-a.a)-arg(b.b-b.a)); return res==0?ok(a.a,b):res<0; } point p[N]; line v[N]; int n; void halfp() { sort(v,v+n,cmp); deque<half> q; deque<point> ans; q.push_back(v[0]); for(int i=1;i<n;i++) { if(dcmp(arg(v[i].b-v[i].a)-arg(v[i-1].b-v[i-1].a))==0) continue; while(ans.size()>0&&!ok(ans.back(),v[i])) { ans.pop_back(); q.pop_back(); } while(ans.size()>0&&!ok(ans.front(),v[i])) { ans.pop_front(); q.pop_front(); } ans.push_back(crosspoint(q.back(),v[i])); q.push_back(v[i]); } while(ans.size()>0&&!ok(ans.back(),q.front())) { ans.pop_back(); q.pop_back(); } while(ans.size()>0&&!ok(ans.front(),q.back())) { ans.pop_front(); q.pop_front(); } ///return ans.size()>0; ans.push_back(crosspoint(q.back(),q.front())); if(ans.size()<3){puts("0.0");return ;} double sum=0; ans.push_back(ans[0]); for(int i=0;i<ans.size()-1;i++)sum+=det(ans[i+1],ans[i]); //if(ans.size()<4)sum=0; printf("%.1f\n",abs(sum/2)); } int main() { while(scanf("%d",&n)!=EOF) { for(int i=0;i<n;i++){v[i].a.input();v[i].b.input();} v[n].a=point(0,0);v[n].b=point(1e4,0);n++; v[n].a=point(1e4,0);v[n].b=point(1e4,1e4);n++; v[n].a=point(1e4,1e4);v[n].b=point(0,1e4);n++; v[n].a=point(0,1e4);v[n].b=point(0,0);n++; ///p[i].input(); p[n]=p[0]; //for(int i=0;i<n;i++)v[i]=line(p[i],p[i+1]); halfp(); } }