#include<stdio.h>
#include<math.h>
#define min(a,b)((a)<(b)?a:b)
#define EPS 1e-8
#define N 10010
struct POINT
{
double x,y;
}p[N],q[N];
int np,nq;
inline double pdis(POINT a,POINT b) //两点之间的距离
{
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
inline double dotcross(POINT p0,POINT p1,POINT p2) // 点积
{
return (p1.x-p0.x)*(p2.x-p0.x)+(p1.y-p0.y)*(p2.y-p0.y);
}
inline double difcross(POINT p0,POINT p1,POINT p2) //叉积
{
return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
}
inline double p2segline(POINT a,POINT p1,POINT p2) //点a到线段p1,p2的距离
{
return fabs(difcross(a,p1,p2)/pdis(p1,p2));
}
inline double p2seg(POINT a,POINT p1,POINT p2) //点a到线段p1,p2的最小距离???
{
if(dotcross(p1,p2,a)<-EPS) return pdis(a,p1);
if(dotcross(p2,p1,a)<-EPS) return pdis(a,p2);
return p2segline(a,p1,p2);
}
inline double FourPoints(POINT p1,POINT p2,POINT q1,POINT q2) //两线段之间的最小距离
{
double ans1=min(p2seg(p1,q1,q2),p2seg(p2,q1,q2));
double ans2=min( p2seg(q1,p1,p2),p2seg(q2,p1,p2));
return min(ans1,ans2);
}
inline double solve(POINT *p,POINT *q,int np,int nq) //一个凸包(q)上的所有点到另一凸包(p)的最小距离
{
p[np]=p[0];
q[nq]=q[0];
int sp=0,sq=0;
for(int i=0;i<np;i++)
if(p[i].y+EPS<p[sp].y)
sp=i;
for( int i=0;i<nq;i++)
if(q[i].y+EPS<q[sq].y)
sq=i;
double tmp,ans=1e99;
for( int i=0;i<np;i++)
{
while((tmp=difcross(q[sq],p[sp],p[sp+1])-difcross(q[sq+1],p[sp],p[sp+1]) ) <-EPS)
sq=(sq+1)%nq;
if(tmp>EPS)
ans=min(ans,p2seg(q[sq],p[sp],p[sp+1]));
else
ans=min(ans,FourPoints(p[sp],p[sp+1],q[sq],q[sq+1]));
sp=(sp+1)%np;
}
return ans;
}
inline double NearestPoints(POINT *p,POINT *q,int np,int nq)
{
return min(solve(p,q,np,nq),solve(q,p,nq,np));
}
int main()
{
int i;
while(scanf("%d%d",&np,&nq)!=EOF)
{
if(np==0 && nq==0)
break;
for(i=0;i<np;i++)
scanf("%lf%lf",&p[i].x,&p[i].y);
for(i=0;i<nq;i++)
scanf("%lf%lf",&q[i].x,&q[i].y);
double ans=NearestPoints(p,q,np,nq);
printf("%.5lf\n",ans);
}
return 0;
}
poj 3608 (旋转卡壳)
最新推荐文章于 2019-08-09 22:45:00 发布