半平面交 poj1279

Source Code

Problem: 1279   User: Faker_fan
Memory: 296K   Time: 0MS
Language: C++   Result: Accepted
    • Source Code
#include 
#include 
#include  #include  #include  #include  typedef long long ll; using namespace std; const int maxn=1e4+10; const int mod=998244353; using namespace std; const double eps = 1e-8; int sgn(double x) { if(fabs(x) < eps)return 0; if(x < 0) return -1; return 1; } struct Point { double x,y; Point(){} Point(double _x,double _y) { x = _x;y = _y; } Point operator -(const Point &b)const { return Point(x - b.x,y - b.y); } double operator ^(const Point &b)const { return x*b.y - y*b.x; } double operator *(const Point &b)const { return x*b.x + y*b.y; } double operator ==(const Point &b)const { return x==b.x&&y==b.y; } }; struct Line { Point s,e; Line(){} Line(Point _s,Point _e) { s = _s;e = _e; } }; double xmult(Point p0,Point p1,Point p2) //p0p1 X p0p2 { return (p1-p0)^(p2-p0); } double xmult(Point p0,Point p1,Point p2,Point p3) //p0p1 X p2p3 { return (p1-p0)^(p3-p2); } bool Seg_inter_line(Line l1,Line l2) //判断直线l1和线段l2是否相交 { return sgn(xmult(l2.s,l1.s,l1.e))*sgn(xmult(l2.e,l1.s,l1.e)) <= 0; } Point getIntersectPoint(Line a, Line b) { double a1 = a.s.y - a.e.y, b1 = a.e.x - a.s.x, c1 = a.s.x * a.e.y - a.e.x * a.s.y; double a2 = b.s.y - b.e.y, b2 = b.e.x - b.s.x, c2 = b.s.x * b.e.y - b.e.x * b.s.y; return Point((c1*b2-c2*b1)/(a2*b1-a1*b2), (a2*c1-a1*c2)/(a1*b2-a2*b1)); } double dist(Point a,Point b) { return sqrt( (b - a)*(b - a) ); } //半平面交s int neihe_num; Point dad_anticlock[maxn],neihe[maxn];//输入弄好就行了 Line dad_half_line[maxn],que[maxn]; //得到极角角度 double getAngle(Point a) { return atan2(a.y, a.x); } //得到极角角度 double getAngle(Line a) { return atan2(a.e.y - a.s.y, a.e.x - a.s.x); } bool onRight(Line a, Line b, Line c) { Point o = getIntersectPoint(b, c); if (((a.e - a.s) ^ (o - a.s)) < 0) return true; return false; } bool cmp_half(Line L1,Line L2) { Point va = L1.e - L1.s, vb = L2.e - L2.s; double A = getAngle(va), B = getAngle(vb); if (fabs((double)(A - B)) < eps) return ((va) ^ (L2.e - L1.s)) >= 0; return A < B; } bool Is_half(int num) { for(int i=0;i;i++) { dad_half_line[i].s=dad_anticlock[i]; dad_half_line[i].e=dad_anticlock[(i+1)%num]; } sort(dad_half_line, dad_half_line+num, cmp_half); int head = 0, tail = 0, cnt = 0;//模拟双端队列 //去重,极角相同时取最后一个。 for (int i = 0; i < num - 1; i++) { if (fabs(getAngle(dad_half_line[i]) - getAngle(dad_half_line[i + 1])) < eps) { continue; } dad_half_line[cnt++] = dad_half_line[i]; } dad_half_line[cnt++] = dad_half_line[num - 1]; for (int i = 0; i < cnt; i++) { //判断新加入直线产生的影响 while(tail - head > 1 && onRight(dad_half_line[i], que[tail - 1], que[tail - 2])) tail--; while(tail - head > 1 && onRight(dad_half_line[i], que[head], que[head + 1])) head++; que[tail++] = dad_half_line[i]; } //最后判断最先加入的直线和最后的直线的影响 while(tail - head > 1 && onRight(que[head], que[tail - 1], que[tail - 2])) tail--; while(tail - head > 1 && onRight(que[tail - 1], que[head], que[head + 1])) head++; if (tail - head < 3) return false; neihe[0]=getIntersectPoint(que[head],que[tail-1]); for(int i=1;i-head;i++) neihe[i]=getIntersectPoint(que[i+head],que[(i+head-1)]); neihe_num=tail-head; return true;//最后拿到的是一些构成内核的线段 } //半平面交e //多边形面积s double mianji_duobianxing(Point *a,int num) { double res=0; for(int i=0;i;i++) { res+=a[i]^a[(i+1)%num]; } res/=2; return abs(res); } //多边形面积e int main() { int n,T; cin>>T; while(T--) { cin>>n; for(int i=0;i;i++) { cin>>dad_anticlock[n-i-1].x>>dad_anticlock[n-i-1].y; } if(Is_half(n)) { double res=0; res=mianji_duobianxing(neihe, neihe_num); printf("%.2lf\n",res); } else { cout<<"0.00"<; } } }

你可能感兴趣的:(半平面交 poj1279)