Uvalive 3890 Most Distant Point from the Sea(半平面交+二分)
来源:互联网 发布:乒乓球入门知乎 编辑:程序博客网 时间:2024/06/06 04:49
题目地址:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1891
思路:
1.求一点到凸包边界最远,即求最大内切圆半径。
2.二分半径r,讲凸包上边像内平移(点p+(normal vector)*r,方向向量v),求半平面交。若交点大于0,此时半径仍可扩大(即所求圆并未与边相切)。若交点等于0,则此时可能存在一内切圆,继续缩小半径。
#include<cmath>#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#define debugusing namespace std;const double eps=1e-6;const double PI=acos(-1.0);const int maxn=200;struct Point{ double x,y; Point() {} Point(double x,double y):x(x),y(y) {} void read() { scanf("%lf%lf",&x,&y); }};typedef Point Vector;Vector operator - (Vector A,Vector B){ return Vector(A.x-B.x,A.y-B.y);}Vector operator + (Vector A,Vector B){ return Vector(A.x+B.x,A.y+B.y);}Vector operator * (Vector A,double t){ return Vector(A.x*t,A.y*t);}double Cross(Vector A,Vector B){ return A.x*B.y-A.y*B.x;}int dcmp(double x){ if(fabs(x)<eps) return 0; else return x<0?-1:1;}double Dot(Vector A,Vector B){ return A.x*B.x+A.y*B.y;}double Length(Vector A){ return sqrt(Dot(A,A));}Vector Normal(Vector A){ double L=Length(A); return Vector(-A.y/L,A.x/L);}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; } Line Move(double d) { Vector tmp=Normal(v); return Line(P+tmp*d,v); }};bool onLeft(Line L,Point p){ return Cross(L.v,p-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); return a.P+a.v*t;}int Half_Plane_Intersection(Line* L,int n,Point* poly){ sort(L,L+n); int first,last; Point* p=new Point[n]; Line* q=new Line[n]; q[first=last=0]=L[0]; for(int i=1; i<n; i++) { while(first<last&&!onLeft(L[i],p[last-1])) last--; while(first<last&&!onLeft(L[i],p[first])) first++; q[++last]=L[i]; if(fabs(Cross(q[last].v,q[last-1].v))<eps) { last--; if(onLeft(q[last],L[i].P)) q[last]=L[i]; } if(first<last) p[last-1]=getIntersection(q[last-1],q[last]); } while(first<last&&!onLeft(q[first],p[last-1])) last--; if(last-first<=1) return 0; p[last]=getIntersection(q[last],q[first]); int m=0; for(int i=first; i<=last; i++) poly[m++]=p[i]; return m;}int n;Line l[maxn];Point p[maxn];int check(double r){ for(int i=0; i<n; i++) { Vector v=Normal(p[(i+1)%n]-p[i]); l[i]=Line(p[i],p[(i+1)%n]-p[i]).Move(r); } Point poly[maxn]; return Half_Plane_Intersection(l,n,poly)==0;}double solve(){ double L=0,R=20000,ans; while(dcmp(R-L)!=0) { double mid=(L+R)/2; if(check(mid)) { ans=mid; R=mid; } else { L=mid; } } return ans;}int main(){#ifdef debu freopen("in.txt","r",stdin);#endif // debug while(scanf("%d",&n)!=EOF&&n) { for(int i=0; i<n; i++) p[i].read(); printf("%.6f\n",solve()); } return 0;}
阅读全文
0 0
- Uvalive 3890 Most Distant Point from the Sea(半平面交+二分)
- (2分+半平面交) Most Distant Point from the Sea UVALive 3890
- poj 3525 Most Distant Point from the Sea(半平面交+二分)
- poj 3525 Most Distant Point from the Sea(半平面交+二分内推进)
- POJ3525-Most Distant Point from the Sea(二分+半平面交)
- UVA 1396 - 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 (半平面交+二分)
- 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 二分+半平面交
- LA3890 Most Distant Point from the Sea 二分+半平面交
- HDU 6144:Arithmetic of Bomb
- Spring_配置类的作用范围、id和name的区别
- ionic 实现音乐后台播放
- Java 位运算(移位、位与、或、异或、非)
- MySql的一些用法总结
- Uvalive 3890 Most Distant Point from the Sea(半平面交+二分)
- 侧滑
- gdfzoj #790 卡尔的连招(状压dp)
- IntelliJ IDEA 智能代码分析
- 比较大小
- eclipse远程调用Hadoop时遇到的问题(1)
- Kaggle正式赛首战top3%分享,小白献给机器学习新手
- 林纳斯·本纳第克特·托瓦兹(Linus Benedict Torvalds)- Linux之父
- 小论文投稿