POJ 3525 Most Distant Point from the Sea
2016-08-02 18:55
288 查看
2016暑期集训6-E
POJ 3525 Most Distant Point from the Sea
半平面交,二分
传送门:POJ传送门:HustOJ
题意
(0,0)开始,逆时针给出一些点,这些点构成一个凸多边形,求多边形内离边界最远的距离。思路
就是二分答案在求半平面交。具体说半平面交,就是给你一堆直线,他们的左边表示有效区域,求所有有效区域的交集(这里模板是返回一组边界点),类似于线性规划的可行域。
所以这题,把直线逆时针组成一个多边形,每条直线左边就是有效区域。二分答案,如果每条直线同时向它的左侧(多边形内测)平移x,那么最远点到边界的距离也减小x,如果半平面交的点集为空,说明平移的x过大。这样二分就行了。
代码
感谢kuangbin大佬的模板#include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> #include <vector> #include <queue> #include <set> #include <map> #include <string> #include <math.h> #include <stdlib.h> #include <time.h> using namespace std; const double eps=1e-8; const double PI=acos(-1.0); const int MAXN=107; int sgn(double x)//符号函数 { if(fabs(x) < eps) return 0; if(x < 0) return -1; else 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; } }; //线 struct Line { Point s,e;//两点 double k;//斜率 Line(){} Line(Point _s,Point _e)//构造 { s=_s; e=_e; k=atan2(e.y-s.y,e.x-s.x); } Point operator &(const Line &b)const//求两直线交点 { Point res=s; double t=((s-b.s)^(b.s-b.e))/((s-e)^(b.s-b.e)); res.x+=(e.x-s.x)*t; res.y+=(e.y-s.y)*t; return res; } }; Line Q[MAXN]; Point p[MAXN];//记录最初给的点集 Line line[MAXN];//由最初的点集生成直线的集合 Point pp[MAXN];//记录半平面交的结果的点集 //半平面交,直线的左边代表有效区域 //直线排序函数 bool HPIcmp(Line a,Line b) { //斜率排序 if(fabs(a.k-b.k) > eps)return a.k < b.k; //斜率相同我也不知道怎么办 return ((a.s-b.s)^(b.e-b.s)) < 0; } //line是半平面交的直线的集合 n是直线的条数 res是结果的点集 resn是点击里面点的个数 void HPI(Line line[],int n,Point res[],int &resn) { int tot=n; sort(line,line+n,HPIcmp); tot=1; for(int i=1;i < n;i++) if(fabs(line[i].k-line[i-1].k) > eps)//去掉斜率重复的 line[tot++]=line[i]; int head=0,tail=1; Q[0]=line[0]; Q[1]=line[1]; resn=0; for(int i=2; i < tot; i++) { if(fabs((Q[tail].e-Q[tail].s)^(Q[tail-1].e-Q[tail-1].s)) < eps||fabs((Q[head].e-Q[head].s)^(Q[head+1].e-Q[head+1].s)) < eps) return; while(head < tail&&(((Q[tail]&Q[tail-1])-line[i].s)^(line[i].e-line[i].s)) > eps) tail--; while(head < tail&&(((Q[head]&Q[head+1])-line[i].s)^(line[i].e-line[i].s)) > eps) head++; Q[++tail]=line[i]; } while(head < tail&&(((Q[tail]&Q[tail-1])-Q[head].s)^(Q[head].e-Q[head].s)) > eps) tail--; while(head < tail&&(((Q[head]&Q[head-1])-Q[tail].s)^(Q[tail].e-Q[tail].e)) > eps) head++; if(tail<=head+1)return; for(int i=head; i < tail; i++) res[resn++]=Q[i]&Q[i+1]; if(head < tail-1) res[resn++]=Q[head]&Q[tail]; } double dist(Point a,Point b)//两点间距离 { return sqrt((a-b)*(a-b)); } //将线段ab往左移动距离p,修改得到线段cd void change(Point a,Point b,Point &c,Point &d,double p) { double len=dist(a,b); /*三角形相似推出下面公式*/ double dx=(a.y-b.y)*p/len; double dy=(b.x-a.x)*p/len; c.x=a.x+dx; c.y=a.y+dy; d.x=b.x+dx; d.y=b.y+dy; } int main() { int n; while(~scanf("%d",&n)&&n!=0) { memset(Q,0,sizeof(Q)); memset(p,0,sizeof(p)); memset(pp,0,sizeof(pp)); memset(line,0,sizeof(line)); for(int i=0;i < n;i++) scanf("%lf%lf",&p[i].x,&p[i].y); double l=0,r=100000; double ans=0; while(r-l>=eps) { double mid=(l+r)/2; for(int i=0;i < n;i++) { Point t1,t2; change(p[i],p[(i+1)%n],t1,t2,mid); line[i]=Line(t1,t2); } int resn; HPI(line,n,pp,resn); //二分 if(resn==0)//等于0说明移多了 r=mid-eps; else { ans=mid; l=mid+eps; } } printf("%.6f\n",ans); } return 0; }
相关文章推荐
- POJ 3525 Most Distant Point from the Sea(半平面交)
- Most Distant Point from the Sea - POJ 3525 求多边形最大内接圆半径
- poj 3525 Most Distant Point from the Sea
- POJ 3525 Most Distant Point from the Sea (banpingmianjiao)
- poj 3525 Most Distant Point from the Sea,半平面交 + 二分
- Poj 3525 Most Distant Point from the Sea (二分+半平面求交)
- POJ 3525 Most Distant Point from the Sea 二分+半平面交
- POJ 3525 Most Distant Point from the Sea
- POJ 3525/UVA 1396 Most Distant Point from the Sea(二分+半平面交)
- POJ 3525 || Most Distant Point from the Sea (凸包求最大内接圆,半平面交内推r
- poj 3525 Most Distant Point from the Sea - 求到海岸最远的点 - 半平面交
- poj 3525 Most Distant Point from the Sea(半平面交+二分内推进)
- POJ 3525 Most Distant Point from the Sea
- POJ3525 Most Distant Point from the Sea(半平面交)
- POJ 3525 Most Distant Point from the Sea (半平面交+二分)
- POJ 3525 Most Distant Point from the Sea 半平面交+二分
- POJ 3525 Most Distant Point from the Sea 二分+内推+半平面交
- 【二分+半平面交】 POJ 3525 Most Distant Point from the Sea
- POJ 3525 Most Distant Point from the Sea 半平面交判多边形存在
- POJ 3525 Most Distant Point from the Sea 二分+半平面交