ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

POJ 3608 Bridge Across Islands

2020-01-17 09:00:41  阅读:276  来源: 互联网

标签:Bridge const Point int res 3608 POJ double return


题意

旋转卡壳。

先找第一个凸包上纵坐标最小的点\(p\)和第二个凸包上纵坐标最大的点\(q\),之后旋转卡壳,求两条线段之间的最短距离。

code:

#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
const int maxn=10010;
const double eps=1e-10;
const double inf=0x3f3f3f3f;
int n,m;
struct Point
{
    double x,y;
    inline double len(){return sqrt(x*x+y*y);}
    Point operator+(const Point a)const
    {
        Point res;
        res.x=x+a.x,res.y=y+a.y;
        return res;
    }
    Point operator-(const Point a)const
    {
        Point res;
        res.x=x-a.x,res.y=y-a.y;
        return res; 
    }
    Point operator*(double k)const
    {
        Point res;
        res.x=x*k,res.y=y*k;
        return res; 
    }
    Point operator/(double k)const
    {
        Point res;
        res.x=x/k,res.y=y/k;
        return res; 
    }
    double operator*(const Point a)const{return x*a.y-y*a.x;}
    double operator&(const Point a)const{return x*a.x+y*a.y;}
};
Point st;
Point p1[maxn],p2[maxn];
inline int dcmp(double x)
{
    if(fabs(x)<=eps)return 0;
    return x<0?-1:1;
}
inline Point get(Point a,Point b){return b-a;}
inline double dis1(Point a,Point b){return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}
inline double dis2(Point a,Point b,Point c)//a->bc
{
    if(!dcmp(get(b,c).len()))return dis1(a,b);
    if(dcmp(get(b,a)&get(b,c))<0)return dis1(a,b);
    if(dcmp(get(c,a)&get(c,b))<0)return dis1(a,c);
    return fabs((get(a,b)*get(a,c))/dis1(b,c));
}
inline double dis3(Point a,Point b,Point c,Point d)
{
    return min(min(dis2(a,c,d),dis2(b,c,d)),min(dis2(c,a,b),dis2(d,a,b)));
}
inline double solve(Point* p1,Point* p2,int n,int m)
{
    int p=0,q=0;
    for(int i=0;i<n;i++)if(p1[i].y<p1[p].y)p=i;
    for(int i=0;i<m;i++)if(p2[i].y>p2[q].y)q=i;
    p1[n]=p1[0];p2[m]=p2[0];
    double res=inf;
    for(int i=0;i<n;i++)
    {
        while(dcmp(get(p1[p],p1[p+1])*get(p2[q],p2[q+1]))>0)q=(q+1)%m;
        res=min(res,dis3(p1[p],p1[p+1],p2[q],p2[q+1]));
        p=(p+1)%n;
    }
    return res;
}
int main()
{
    //freopen("test.in","r",stdin);
    //freopen("test.out","w",stdout);
    while(~scanf("%d%d",&n,&m)&&n&&m)
    {
        for(int i=0;i<n;i++)scanf("%lf%lf",&p1[i].x,&p1[i].y);
        for(int i=0;i<m;i++)scanf("%lf%lf",&p2[i].x,&p2[i].y);
        for(int i=0;i<n-2;i++)
            if(dcmp(get(p1[i],p1[i+1])*get(p1[i+1],p1[i+2]))<0){reverse(p1,p1+n);break;}
            else if(dcmp(get(p1[i],p1[i+1])*get(p1[i+1],p1[i+2]))>0)break;  
        for(int i=0;i<m-2;i++)
            if(dcmp(get(p2[i],p2[i+1])*get(p2[i+1],p2[i+2]))<0){reverse(p2,p2+m);break;}
            else if(dcmp(get(p2[i],p2[i+1])*get(p2[i+1],p2[i+2]))>0)break;
        printf("%.5lf\n",solve(p1,p2,n,m));
    }
    return 0;
}

标签:Bridge,const,Point,int,res,3608,POJ,double,return
来源: https://www.cnblogs.com/nofind/p/12204140.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有