hdu12823(两凸包之间最短距离)

来源:互联网 发布:反恐数据库外泄 编辑:程序博客网 时间:2024/06/07 20:13

两凸包间最短距离

#include<iostream>

#include<cstdio>

#include<cstring>

#include<algorithm>

#include<cmath>

#define N 1003

#define eps 1e-8

using namespacestd;

struct vector {

    double x,y;

    vector (double X=0,double Y=0){

        x=X,y=Y;

    }

}p[N],q[N],ch[N];

double ans;

int n,m;

typedef vector point;

vector operator -(vector a,vector b){returnvector (a.x-b.x,a.y-b.y);}

vector operator +(vector a,vector b){returnvector (a.x+b.x,a.y+b.y);}

vector operator *(vector a,double t){returnvector (a.x*t,a.y*t);}

vector operator /(vector a,double t){returnvector (a.x/t,a.y/t);}

bool operator <(vector a,vector b)

{

    return a.x<b.x||a.x==b.x&&a.y<b.y;

}

bool operator ==(vector a,vector b)

{

    return a.x==b.x&&a.y==b.y;

}

int dcmp(double x)

{

    if (fabs(x)<eps)return0;

    return x<0?-1:1;

}

double cross(vector a,vector b)

{

    return a.x*b.y-a.y*b.x;

}

bool segment(point a,point b,point c,point d)

{

    double c1=cross(b-a,c-a),c2=cross(b-a,d-a);

    double d1=cross(d-c,a-c),d2=cross(d-c,b-c);

    returndcmp(c1)*dcmp(c2)<0&&dcmp(d1)*dcmp(d2)<0;

}

double dot(vector a,vector b)

{

    return a.x*b.x+a.y*b.y;

}

double len(vector a)

{

    returnsqrt(a.x*a.x+a.y*a.y);

}

double dists(point p,point a,point b)

{

    if (a==b)returnlen(p-a);

    vector v1=b-a,v2=p-a,v3=p-b;

    if (dcmp(dot(v1,v2))<0)returnlen(v2);

    else if (dcmp(dot(v1,v3))>0)returnlen(v3);

    returnfabs(cross(v1,v2))/len(v1);

}

double distl(point p,point a,point b)

{

    vector v=p-a;vector u=b-a;

    returnfabs(cross(v,u))/len(u);

}

void convexhull(point *a,int &n)

{

    sort(a,a+n);

    int cnt=0;

    if (n==1) {

        ch[cnt++]=a[0];

        n=cnt;

        for (int i=0;i<cnt;i++) a[i]=ch[i];

        return;

    }

    for (int i=0;i<n;i++){

        while (cnt>1&&cross(ch[cnt-1]-ch[cnt-2],a[i]-ch[cnt-2])<=0) cnt--;

        ch[cnt++]=a[i];

    }

    int k=cnt;

    for (int i=n-2;i>=0;i--){

        while (cnt>k&&cross(ch[cnt-1]-ch[cnt-2],a[i]-ch[cnt-2])<=0) cnt--;

        ch[cnt++]=a[i];

    }

    cnt--;

    n=cnt;

    for (int i=0;i<cnt;i++) a[i]=ch[i];

}

void rotating(point *p,point *q,int n,int m)

{

    int x=0;int y=0;

    double t;

    for (int i=0;i<n;i++) x=(p[i].y<p[x].y)?i:x;

    for (int i=0;i<m;i++) y=(q[i].y>q[y].y)?i:y;

    for (int i=0;i<n;i++){

        while (t=dcmp(cross(p[x]-p[x+1],q[y+1]-q[y]))<0)

            y=(y+1)%m;

        if (t==0) {

            ans=min(ans,dists(p[x],q[y+1],q[y]));

            ans=min(ans,dists(p[x+1],q[y+1],q[y]));

            ans=min(ans,dists(q[y],p[x],p[x+1]));

            ans=min(ans,dists(q[y+1],p[x],p[x+1]));

            //ans=min(ans,distl(p[x],q[y+1],q[y]));

        }

        elseans=min(ans,dists(q[y],p[x],p[x+1]));

        x=(x+1)%n;

    }

}

bool pointin(point a,point *p,int n)

{

    bool pd=false;

    int t=0;

    for (int i=0;i<n;i++)

        if (dcmp(cross(p[i+1]-p[i],a-p[i]))>=0) t++;

    if (t==n)returntrue;

    elsereturnfalse;

}

bool check()

{

    for (int i=0;i<n;i++) {

        for (int j=0;j<m;j++)

            if (segment(p[i],p[i+1],q[j],q[j+1]))returnfalse;

    }

    returntrue;

}

bool polyin()

{

    for (int i=0;i<n;i++)

        for (int j=0;j<m;j++)

            if (p[i]==q[j])returntrue;

    bool pd=false;

    for (int i=0;i<n;i++){

        if (pointin(p[i],q,m)) pd=true;

    }

    bool pd1=false;

    for (int i=0;i<m;i++){

        if (pointin(q[i],p,n)) pd1=true;

    }

    return pd||pd1;

}

int main()

{

    while (scanf("%d%d",&n,&m)!=EOF){

        for (int i=0;i<n;i++)scanf("%lf%lf",&p[i].x,&p[i].y);

        for (int i=0;i<m;i++)scanf("%lf%lf",&q[i].x,&q[i].y);

        convexhull(p,n);

        convexhull(q,m);

        p[n]=p[0];

        q[m]=q[0];

        ans=1000000000;

        if(n>m)swap(n,m),swap(p,q);

        if (n==1) {

            if (m==1)ans=len(p[0]-q[0]);

            else {

                if (m==2)ans=dists(p[0],q[0],q[1]);

                else {

                    if (pointin(p[0],q,m))ans=0.0000;

                    elsefor (int i=0;i<m;i++)

                        ans=min(ans,dists(p[0],q[i],q[i+1]));

                }

            }

            printf("%.4lf\n",ans);

            continue;

        }

        if (n==2) {

            if (m==2) {

                ans=min(ans,dists(p[0],q[0],q[1]));

                ans=min(ans,dists(p[1],q[0],q[1]));

                ans=min(ans,dists(q[0],p[0],p[1]));

                ans=min(ans,dists(q[1],p[0],p[1]));

            }

            else {

                for (int i=0;i<=1;i++)

                    if (pointin(p[i],q,m))

                        ans=0.0000;

                if (!check())ans=0.0000;

                for (int i=0;i<m;i++){

                    ans=min(ans,dists(p[0],q[i],q[i+1]));

                    ans=min(ans,dists(p[1],q[i],q[i+1]));

                    ans=min(ans,dists(q[i],p[0],p[1]));

                    ans=min(ans,dists(q[i+1],p[0],p[1]));

                }

            }

            printf("%.4lf\n",ans);

            continue;

        }

        bool pd=check();

        if (!pd||polyin()) {

            printf("0.0000\n");

            continue;

        }

        rotating(p,q,n,m);

        rotating(q,p,m,n);

        printf("%.4lf\n",ans);

    }  




感觉自己一事无成呢,但还是要多努力

保持身体健康