您的位置:首页 > 其它

POJ 3525 Most Distant Point from the Sea

2015-01-23 11:28 330 查看
这道题关键点就在于线段的平移,把线段向着其半平面方向移动r的距离,具体做法风注释

再说说一直错的点,刚开始把点方向规整化的部分写在循环里了,导致这部分一直在执行,实际上只执行一次就可以了。。

#include<stdio.h>
#include<math.h>
#include<algorithm>
using namespace std;
const double eps=1e-6;
struct Point {
double x,y;
Point (){};
Point (double xx,double yy) {x=xx;y=yy;}
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;
}
};
struct Line {
Point s,e;
double angle;
Line(){};
Line(Point ss,Point ee){s=ss;e=ee;}
Point operator &(const Line b) {
Point res=s;
double t=((s-b.e)^(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;
}
};
int n,m;
Point p[105];
Line l[105],dq[105];
void init(double r) {

for(int i=0;i<n;i++) {
//把点进行偏移后把点加入线段中
double dy,dx,len;
Point ta,tb;
dx=p[i+1].y-p[i].y;
dy=p[i].x-p[i+1].x;
len=sqrt(dx*dx+dy*dy);
ta.x=p[i].x+dx*r/len;
ta.y=p[i].y+dy*r/len;
tb.x=p[i+1].x+dx*r/len;
tb.y=p[i+1].y+dy*r/len;
l[i].s=ta;    l[i].e=tb;
l[i].angle=atan2(l[i].e.y-l[i].s.y,l[i].e.x-l[i].s.x);
}
}
int cmp(Line a,Line b) {
if (fabs(a.angle-b.angle)<eps) return ((a.e-a.s)^(b.s-a.s))>eps;//即b在a的左方,留下a
else return a.angle<b.angle;
}
int EqualPoint(Point a,Point b) {
return b.x-a.x==0 && b.y-a.y==0;
}
int HPI(double r) {

init(r);
sort(l,l+n,cmp);
int ln;
for(int i=1,j=0;i<n;i++) {
if (l[i].angle-l[j].angle>eps) l[++j]=l[i];
ln=j+1;
}
dq[0]=l[0]; dq[1]=l[1];
int bot=0,top=1;
for(int i=2;i<ln;i++) {
while (bot<top && ((l[i].e-l[i].s)^((dq[top]&dq[top-1])-l[i].s))>eps) top--;
while (bot<top && ((l[i].e-l[i].s)^((dq[bot]&dq[bot+1])-l[i].s))>eps) bot++;
dq[++top]=l[i];
}
while (bot<top && ((dq[bot].e-dq[bot].s)^((dq[top]&dq[top-1])-dq[bot].s))>eps) top--;
while (bot<top && ((dq[top].e-dq[top].s)^((dq[bot]&dq[bot+1])-dq[top].s))>eps) bot++;
if (top<=bot+1) return 0;
else return 1;
m=0;
dq[++top]=dq[bot];
for(int i=bot;i<top;i++) {
p[m++]=dq[i]&dq[i+1];
}
m=unique(p,p+m,EqualPoint)-p;
if(m>0) return 1;
else return 0;

}
int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif // ONLINE_JUDGE

while(scanf("%d",&n) && n) {

for(int i=0;i<n;i++) scanf("%lf%lf",&p[i].x,&p[i].y);
for(int i=0;i<n/2;i++) swap(p[i],p[n-1-i]);//把点变成顺时针的
//for(int i=0;i<n;i++) printf("%.2lf  %.2lf\n",p[i].x,p[i].y);
p
=p[0];
double high=20000,low=0;
double mid;
while(low+eps<=high) {
mid=(high+low)/2.0;
if (HPI(mid)) low=mid;
else high=mid;//没有交点则说明mid过大
}
printf("%f\n",high);

}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: