HDU 4316 凸包 +半平面交
来源:互联网 发布:slideunlock.js 编辑:程序博客网 时间:2024/06/06 05:56
题意:给出多边形的顶点,然后在天花板有三个摄像头,找出三个摄像头的盲区。
思路:每一个摄像头 对应有一个盲区,然后把三个摄像头的盲区取交集 然后求面积就可以 这里用到了 凸包模版和半平面交模版
代码:
#include<cmath>#include<cstdio>#include<iostream>#include<algorithm>using namespace std;struct Point{ double x,y,z; Point(double x=0,double y=0,double z=0):x(x),y(y),z(z) {}};Point tmp[200];const double eps=1e-8;typedef Point Vector;Vector operator -(Point A,Point B){ return Vector(A.x-B.x,A.y-B.y);}Vector operator +(Point A,Point 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);}double Cross(Vector A,Vector B){ return A.x*B.y-A.y*B.x;}int n,res[1200],top;Point p[1200];bool mult(Point sp,Point ep,Point op){ return (sp.x-op.x)*(ep.y-op.y)>=(ep.x-op.x)*(sp.y-op.y);}bool cmp(Point a,Point b){ if(a.y==b.y)return a.x<b.x; return a.y<b.y;}struct Line{ Point P; Vector v; double ang; Line(){} Line(Point P,Vector v):P(P),v(v){ ang=atan2(v.y,v.x); } bool operator <(const Line &L)const{ return ang<L.ang; }};bool Onleft(Line L,Point pp){ return Cross(L.v,pp-L.P)>0;}Point GetIntersection(Line a,Line b){ Vector u=a.P-b.P; double t=Cross(b.v,u)/Cross(a.v,b.v); // cout<<t<<endl; return a.P+a.v*t;}void Graham(){ int len; top=1; sort(p,p+n,cmp); if(n==0)return;res[0]=0; if(n==1)return;res[1]=1; if(n==2)return;res[2]=2; for(int i=2;i<n;i++){ while(top&&mult(p[i],p[res[top]],p[res[top-1]]))top--; res[++top]=i; } len=top; res[++top]=n-2; for(int i=n-3;i>=0;i--){ while(top!=len&&mult(p[i],p[res[top]],p[res[top-1]]))top--; res[++top]=i; }}int HalfplaneIntersection(Line* L,int n,Point *poly){ sort(L,L+n); int ft,la; Point *pp=new Point[n]; Line *q=new Line[n]; q[ft=la=0]=L[0]; for(int i=1;i<n;++i) { while (ft<la&&!Onleft(L[i],pp[la-1])) --la; while (ft<la&&!Onleft(L[i], pp[ft])) ++ft; q[++la]=L[i]; if(fabs(Cross(q[la].v,q[la-1].v))<eps){ la--; if (Onleft(q[la], L[i].P)) q[la]=L[i]; } if(ft<la){ pp[la-1]=GetIntersection(q[la-1],q[la]); // cout<<pp[la-1].x<<" "<<pp[la-1].y<<endl; } } while (ft<la&&!Onleft(q[ft],pp[la-1])) --la; if (la-ft<=1) return 0; pp[la]=GetIntersection(q[la],q[ft]); int m=0; for (int i=ft; i<=la; ++i) { poly[m++]=pp[i]; } return m;}int main(){ Point a[3];Line l[1000]; while (cin>>n) { for (int i=0; i<n; ++i) cin>>tmp[i].x>>tmp[i].y>>tmp[i].z; for (int i=0; i<3; ++i) cin>>a[i].x>>a[i].y; int tol=0; for (int i=0; i<3; ++i) { for (int j=0; j<n; ++j) { p[j].x=-100.0*(tmp[j].x-a[i].x)/(tmp[j].z-100)+a[i].x; p[j].y=-100.0*(tmp[j].y-a[i].y)/(tmp[j].z-100)+a[i].y; } Graham(); // cout<<top<<endl; for (int j=0;j<top; ++j){ // cout<<p[j].x<<" "<<p[j].y<<endl; l[tol++]=Line(p[res[j]],p[res[(j+1)%top]]-p[res[j]]); } // cout<<endl; } // cout<<tol<<endl; int m=HalfplaneIntersection(l, tol, tmp); // cout<<m<<endl; double ans=0; for (int i=2; i<m; ++i) { ans+=Cross(tmp[i-1]-tmp[0],tmp[i]-tmp[0]); } printf("%.2f\n",ans/2.0); } return 0;}
阅读全文
0 0
- HDU 4316 凸包 +半平面交
- HDU 4316 凸包+半面相交
- HDU 2297 半平面交
- 代码备份:动态维护半平面交/凸包
- POJ 3384 Feng Shui 凸包直径 + 半平面交
- 大白 计算几何专题 凸包、半平面交、平面区域 部分例题练习题总结
- hdu 4327 简单立体几何 + 半平面交
- hdu - 4327 - Shooting - 立体几何 + 半平面交
- hdu 5462 Manors(半平面交)
- HDU 3761 (二分 半平面交)
- hdu 2297 Run 半平面交
- HDU 3982 半平面交+圆与多边形面积交
- HDU 3982 (半平面交 多边形和圆面积交)
- [半平面交对偶凸包] BZOJ 1007 [HNOI2008]水平可见直线
- [凸包最大内接圆 二分 半平面交] POJ 3525 Most Distant Point from the Sea
- pku2451 半平面交
- 半平面交
- 半平面交
- Codeforces Round #416 (Div. 2) A. Vladik and Courtesy
- 指针数组
- HDU
- MediaMetadataRetrieverCompat
- NOI前50天的机房日常
- HDU 4316 凸包 +半平面交
- 递归创建二叉树以及一些基本操作
- 50 years, 50 colors 【最小顶点覆盖】
- LeetCode 387. First Unique Character in a String(unordered_map元素顺序杂乱性)
- Java IO2
- DFS- SDUT1269 走迷宫
- 【8086汇编】基础排序之希尔排序
- ubuntu下php环境安装
- 存储系统