poj 2451 (半平面求交)
来源:互联网 发布:js数组中对象的属性 编辑:程序博客网 时间:2024/05/22 12:45
半平面求交,按着zzy论文里的方法对着写就可以了,这题数据还是比较厚道的
#include<stdio.h>#include<math.h>#include<algorithm>using namespace std;#define eps 1e-8const int maxn=20005;int dcmp(double k){ return (k>eps)-(k<-eps);}struct point{ double x,y; point(double xx=0,double yy=0){ x=xx;y=yy;} point rev(point r){ return point(2*x-r.x,2*y-r.y);} point operator-(point r){ return point(x-r.x,y-r.y);} point operator+(point r){ return point(x+r.x,y+r.y);} bool operator==(point r){ return !dcmp(x-r.x)&&!dcmp(y-r.y);} int operator*(point r){ return dcmp(r.x*y-x*r.y);} void print(){ printf("(%lf,%lf)\n",x,y);}}p_down[maxn],p_up[maxn],list[maxn];struct line{ point u,v; line(point uu=point(0,0),point vv=point(0,0)){ u=uu;v=vv;} void init(){ scanf("%lf%lf%lf%lf",&u.x,&u.y,&v.x,&v.y);} int operator*(line r){ return (v-u)*(r.v-r.u);} bool str(){ return !dcmp(u.x-v.x)&&dcmp(v.y-u.y)<0;} void print(){ printf("(%lf,%lf),(%lf,%lf)\n",u.x,u.y,v.x,v.y);}}q[maxn],l_down[maxn],l_up[maxn],pivot,l1,l2,l3,l4;point intersection(point u1,point u2,point v1,point v2){//直线交点point ret=u1;double t=((u1.x-v1.x)*(v1.y-v2.y)-(u1.y-v1.y)*(v1.x-v2.x))/((u1.x-u2.x)*(v1.y-v2.y)-(u1.y-u2.y)*(v1.x-v2.x));ret.x+=(u2.x-u1.x)*t;ret.y+=(u2.y-u1.y)*t;return ret;}double area_polygon(point* p,int k){//多边形面积double s1=0,s2=0;for(int i=0;i<k;i++)s1+=p[(i+1)%k].y*p[i].x,s2+=p[(i+1)%k].y*p[(i+2)%k].x;return fabs(s1-s2)/2;}int cmp(line a,line b){ return a*b<0||a.str()&&!b.str();}bool is_left(line a,line b){ return a*line(a.u,b.v)>0;}int n;int cnt_down,cnt_up;int top_down,top_up;void init(){ l1=line(point(-1,0),point(10001,0)); l2=line(point(10001,10000),point(-1,10000)); l3=line(point(10000,-1),point(10000,10001)); l4=line(point(0,10001),point(0,-1)); q[0]=l1;q[1]=l2;q[2]=l3;q[3]=l4; n+=4; for(int i=4;i<n;i++) q[i].init(); cnt_down=cnt_up=0; for(int i=0;i<n;i++){ if(q[i]*pivot>=0) l_down[cnt_down++]=q[i]; else l_up[cnt_up++]=q[i]; } sort(l_down,l_down+cnt_down,cmp); sort(l_up,l_up+cnt_up,cmp); int ct1,ct2; ct1=1; for(int i=1;i<cnt_down;i++){ if(l_down[i]*l_down[ct1-1]>0) l_down[ct1++]=l_down[i]; else if(is_left(l_down[i],l_down[ct1-1])) l_down[ct1-1]=l_down[i]; } cnt_down=ct1; ct2=1; for(int i=1;i<cnt_up;i++){ if(l_up[i]*l_up[ct2-1]>0) l_up[ct2++]=l_up[i]; else if(is_left(l_up[i],l_up[ct2-1])) l_up[ct2-1]=l_up[i]; } cnt_up=ct2; top_down=0; p_down[0]=l_down[0].u; point rear,now; rear=l_down[0].v; for(int i=1;i<cnt_down;i++){ point now=intersection(p_down[top_down],rear,l_down[i].u,l_down[i].v); while(top_down&&now.x<=p_down[top_down].x){ top_down--; now=intersection(p_down[top_down],p_down[top_down+1],l_down[i].u,l_down[i].v); } p_down[++top_down]=now; rear=l_down[i].v==now?l_down[i].u:l_down[i].v; } p_down[++top_down]=rear; int t1=(p_down[1]-p_down[0])*point(0,-1); int t2=(p_down[top_down]-p_down[top_down-1])*point(0,-1); if(t1<0||t1==0&&p_down[1].y>p_down[0].y) p_down[0]=p_down[1].rev(p_down[0]); if(t2<0||t2==0&&p_down[top_down].y<p_down[top_down-1].y) p_down[top_down]=p_down[top_down-1].rev(p_down[top_down]); top_up=0; p_up[0]=l_up[0].u; rear=l_up[0].v; for(int i=1;i<cnt_up;i++){ point now=intersection(p_up[top_up],rear,l_up[i].u,l_up[i].v); while(top_up&&now.x>=p_up[top_up].x){ top_up--; now=intersection(p_up[top_up],p_up[top_up+1],l_up[i].u,l_up[i].v); } p_up[++top_up]=now; rear=l_up[i].v==now?l_up[i].u:l_up[i].v; } p_up[++top_up]=rear; if((p_up[1]-p_up[0])*point(0,-1)>=0) p_up[0]=p_up[1].rev(p_up[0]); if((p_up[top_up]-p_up[top_up-1])*point(0,-1)>=0) p_up[top_up]=p_up[top_up-1].rev(p_up[top_up]);}point ll,rr;int ct1,ct2,p1,p2,p3,p4;double area(){ ct1=1;ct2=top_up-1; bool find=false; while(ct1<=top_down&&ct2>=0){ if((p_up[ct2]-p_up[ct2+1])*(p_down[ct1]-p_up[ct2+1])<=0) ct1++; else if((p_down[ct1]-p_down[ct1-1])*(p_up[ct2]-p_down[ct1-1])>=0) ct2--; else{ ll=intersection(p_down[ct1-1],p_down[ct1],p_up[ct2],p_up[ct2+1]); p1=ct2;p2=ct1; find=true; break; } } if(!find){ //puts("fail!"); return 0; } ct1=top_down-1;ct2=1; while(ct2<=top_up&ct1>=0){ if((p_down[ct1]-p_down[ct1+1])*(p_up[ct2]-p_down[ct1+1])<=0) ct2++; else if((p_up[ct2]-p_up[ct2-1])*(p_down[ct1]-p_up[ct2-1])>=0) ct1--; else{ rr=intersection(p_up[ct2-1],p_up[ct2],p_down[ct1],p_down[ct1+1]); p3=ct2;p4=ct1; break; } } int ct=0; list[ct++]=ll; for(int i=p1;i>=p3;i--) list[ct++]=p_up[i]; list[ct++]=rr; for(int i=p4;i>=p2;i--) list[ct++]=p_down[i]; return area_polygon(list,ct);}int main(){ pivot.u=point(0,0);pivot.v=point(0,-1); while(scanf("%d",&n)!=EOF){ init(); printf("%.1lf\n",area()+eps); } return 0;}
- poj 2451 (半平面求交)
- POJ 2451 Uyuw's Concert(半平面交求面积)
- POJ 2451 Uyuw's Concert 半平面交求面积
- poj 2540 求半平面交
- 【poj 2451】半平面交
- 半平面求交
- poj 2451 半平面交模板
- POJ 2451 (半平面交 板子题)
- poj 1474 半平面交求多边形的核
- POJ 2540 Hotter Colder(半平面交求可行域)
- Poj 3384 Feng Shui (半平面求交应用)
- Poj 1755 Triathlon (半平面交求可行域)
- POJ 2540 半平面交求可行区域面积
- POJ 3335 半平面交求多边形的核
- poj 1279 求半平面交的 面积(推荐)
- POJ 3335 Rotating Scoreboard 半平面交求多边形内核
- POJ 1279 Art Gallery (半平面交求面积)
- POJ 1279 Art Gallery 半平面交求面积
- nutch-1.3 分布式terminal操作过程
- 图片转换成二进制度
- Com、Com+\DCom定义和差别
- Effective C#阅读笔记-8Prefer Variable Initializers to Assignment Statements
- 1Understanding How Expression Web Works
- poj 2451 (半平面求交)
- VC中加载外部动态链接库的步骤:
- CoMarshalInterThreadInterfaceInStream 注意几点
- 程序员的生存法则
- 粵語文法句式
- 求两个有序数组的中位数
- 卡片游戏
- mvc flex cairngrom
- istream_iterator和ostream_iterator学习体会