Codeforces problem 67E(多边形求内核的应用)
生活随笔
收集整理的這篇文章主要介紹了
Codeforces problem 67E(多边形求内核的应用)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目:E. Save the City!
?
/*Goujinping 2013.4.12 NEFUThe masterplate of Polygon kernel.Now the global variable Area stand for the area of Polygon kernelIn most case,the problem let us judge whether the Polygon kernel exist or not and calculate the area,perimeter,or other constants about the Polygon kernel.*/#include <math.h> #include <stdio.h> #include <iostream> #include <algorithm>using namespace std;const int N=11111; const double EPS = 1e-8;typedef double DIY;DIY Area,Length;struct Point {DIY x,y;Point() {}Point(DIY _x,DIY _y):x(_x),y(_y) {} } p[N];Point MakeVector(Point &P,Point &Q) {return Point(Q.x-P.x,Q.y-P.y); }DIY CrossProduct(Point P,Point Q) {return P.x*Q.y-P.y*Q.x; }DIY MultiCross(Point P,Point Q,Point R) {return CrossProduct(MakeVector(Q,P),MakeVector(Q,R)); }struct halfPlane {Point s,t;DIY angle;halfPlane() {}halfPlane(Point _s,Point _t):s(_s),t(_t) {}halfPlane(DIY sx,DIY sy,DIY tx,DIY ty):s(sx,sy),t(tx,ty) {}void GetAngle(){angle=atan2(t.y-s.y,t.x-s.x);} } hp[N],q[N];Point IntersectPoint(halfPlane P,halfPlane Q) {DIY a1=CrossProduct(MakeVector(P.s,Q.t),MakeVector(P.s,Q.s));DIY a2=CrossProduct(MakeVector(P.t,Q.s),MakeVector(P.t,Q.t));return Point((P.s.x*a2+P.t.x*a1)/(a2+a1),(P.s.y*a2+P.t.y*a1)/(a2+a1)); }bool cmp(halfPlane P,halfPlane Q) {if(fabs(P.angle-Q.angle)<EPS)return MultiCross(P.s,P.t,Q.s)>0;return P.angle<Q.angle; }bool IsParallel(halfPlane P,halfPlane Q) {return fabs(CrossProduct(MakeVector(P.s,P.t),MakeVector(Q.s,Q.t)))<EPS; }void HalfPlaneIntersect(int n,int &m) {sort(hp,hp+n,cmp);int i,l=0,r=1;for(m=i=1; i<n; ++i)if(hp[i].angle-hp[i-1].angle>EPS) hp[m++]=hp[i];n=m; m=0;q[0]=hp[0];q[1]=hp[1];for(i=2; i<n; i++){if(IsParallel(q[r],q[r-1])||IsParallel(q[l],q[l+1])) return;while(l<r&&MultiCross(hp[i].s,hp[i].t,IntersectPoint(q[r],q[r-1]))>0) --r;while(l<r&&MultiCross(hp[i].s,hp[i].t,IntersectPoint(q[l],q[l+1]))>0) ++l;q[++r]=hp[i];}while(l<r&&MultiCross(q[l].s,q[l].t,IntersectPoint(q[r],q[r-1]))>0) --r;while(l<r&&MultiCross(q[r].s,q[r].t,IntersectPoint(q[l],q[l+1]))>0) ++l;q[++r]=q[l];for(i=l; i<r; ++i)p[m++]=IntersectPoint(q[i],q[i+1]); }void Solve(Point *p,int n,int &m) {int i,j;Point a,b;p[n]=p[0];for(i=0;i<n;i++){hp[i]=halfPlane(p[(i+1)%n],p[i]);hp[i].GetAngle();}a=p[0],b=p[1];HalfPlaneIntersect(n,m);Area=0;Length=0;if(m>2){if(a.x>b.x) swap(a,b);int f2=0,f1=0;for(int i=0; i<m; i++){if(p[i].y==a.y&&p[(i+1)%m].y==a.y){f2=1;a=p[i];b=p[(i+1)%m];break;}else if(p[i].y==a.y)f1=1;}if(f1&&!f2)Length=1;else if(f2){if(a.x>b.x)swap(a,b);Length=(int)(b.x-a.x)+1;}}if(m>2){p[m]=p[0];for(i=0;i<m;++i)Area+=CrossProduct(p[i],p[i+1]);if(Area<0) Area=-Area;}Area/=2.0; }int main() {int n,m;while(cin>>n){for(int i=0; i<n; i++)cin>>p[i].x>>p[i].y;Solve(p,n,m);cout<<Length<<endl;}return 0; }
?
總結
以上是生活随笔為你收集整理的Codeforces problem 67E(多边形求内核的应用)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: NEFU 635(二分+枚举)
- 下一篇: POJ3335(判断多边形内核是否存在)