#include <iostream>
#include <cmath>
#include <vector>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <algorithm>
using namespace std; #define MAX_N 110 /*------------------常量区-------------------*/ const double INF = 1e10; // 无穷大
const double EPS = 1e-; // 计算精度
const double PI = acos(-1.0);// PI
const int PINXING = ; // 平行
const int XIANGJIAO = ; // 相交
const int XIANGLI = ; // 相离
const int GONGXIAN = ; // 共线
const int CHONGDIE = -; // 重叠
const int INSIDE = ; // 点在图形内部
const int OUTSIDE = ; // 点在图形外部
const int BORDER = ; // 点在图形边界 /*-----------------类型定义区----------------*/ struct Point { // 二维点或矢量
double x, y;
//double angle, dis;
Point() {}
Point(double x0, double y0): x(x0), y(y0) {}
void read()
{
scanf("%lf%lf",&x,&y);
}
};
struct Point3D { //三维点或矢量
double x, y, z;
Point3D() {}
Point3D(double x0, double y0, double z0): x(x0), y(y0), z(z0) {}
};
struct Line { // 二维的直线或线段
Point p1, p2;
Line() {}
Line(Point p10, Point p20): p1(p10), p2(p20) {}
void read()
{
scanf("%lf%lf%lf%lf",&p1.x,&p1.y,&p2.x,&p2.y);
}
};
struct Line3D { // 三维的直线或线段
Point3D p1, p2;
Line3D() {}
Line3D(Point3D p10, Point3D p20): p1(p10), p2(p20) {}
};
struct Rect { // 用长宽表示矩形的方法 w, h分别表示宽度和高度
double w, h;
Rect() {}
Rect(double _w,double _h) : w(_w),h(_h) {}
};
struct Rect_2 { // 表示矩形,左下角坐标是(xl, yl),右上角坐标是(xh, yh)
double xl, yl, xh, yh;
Rect_2() {}
Rect_2(double _xl,double _yl,double _xh,double _yh) : xl(_xl),yl(_yl),xh(_xh),yh(_yh) {}
};
struct Circle { //圆
Point c;
double r;
Circle() {}
Circle(Point _c,double _r) :c(_c),r(_r) {}
}; typedef vector<Point> Polygon; // 二维多边形
typedef vector<Point> Points; // 二维点集 /*-------------------基本函数区---------------------*/ inline double max(double x,double y)
{
return x > y ? x : y;
}
inline double min(double x, double y)
{
return x > y ? y : x;
}
inline bool ZERO(double x) // x == 0
{
return (fabs(x) < EPS);
}
inline bool ZERO(Point p) // p == 0
{
return (ZERO(p.x) && ZERO(p.y));
}
inline bool ZERO(Point3D p) // p == 0
{
return (ZERO(p.x) && ZERO(p.y) && ZERO(p.z));
}
inline bool EQ(double x, double y) // eqaul, x == y
{
return (fabs(x - y) < EPS);
}
inline bool NEQ(double x, double y) // not equal, x != y
{
return (fabs(x - y) >= EPS);
}
inline bool LT(double x, double y) // less than, x < y
{
return ( NEQ(x, y) && (x < y) );
}
inline bool GT(double x, double y) // greater than, x > y
{
return ( NEQ(x, y) && (x > y) );
}
inline bool LEQ(double x, double y) // less equal, x <= y
{
return ( EQ(x, y) || (x < y) );
}
inline bool GEQ(double x, double y) // greater equal, x >= y
{
return ( EQ(x, y) || (x > y) );
} // 输出浮点数前,防止输出-0.00调用该函数进行修正!
inline double FIX(double x)
{
return (fabs(x) < EPS) ? : x;
} /*------------------二维矢量运算重载区---------------------*/
bool operator==(Point p1, Point p2)
{
return ( EQ(p1.x, p2.x) && EQ(p1.y, p2.y) );
}
bool operator!=(Point p1, Point p2)
{
return ( NEQ(p1.x, p2.x) || NEQ(p1.y, p2.y) );
}
bool operator<(Point p1, Point p2)
{
if (NEQ(p1.x, p2.x)) {
return (p1.x < p2.x);
} else {
return (p1.y < p2.y);
}
}
Point operator+(Point p1, Point p2)
{
return Point(p1.x + p2.x, p1.y + p2.y);
}
Point operator-(Point p1, Point p2)
{
return Point(p1.x - p2.x, p1.y - p2.y);
}
double operator*(Point p1, Point p2) // 计算叉乘 p1 × p2
{
return (p1.x * p2.y - p2.x * p1.y);
}
double operator&(Point p1, Point p2) { // 计算点积 p1·p2
return (p1.x * p2.x + p1.y * p2.y);
}
double Norm(Point p) // 计算矢量p的模
{
return sqrt(p.x * p.x + p.y * p.y);
} /*-------------------基本函数区------------------*/ //得到两点之间的距离
double Dis(Point p1,Point p2)
{
return sqrt( (p1.x-p2.x)*(p1.x-p2.x) + (p1.y-p2.y)*(p1.y-p2.y) );
} //求二维平面上点到直线的距离
double Dis(Point p, Line L)
{
return ( fabs((p - L.p1) * (L.p2 - L.p1)) / Norm(L.p2 - L.p1) );
} //得到两点之间距离的平方,为减少误差用
double Dis2(Point p1,Point p2)
{
return (p1.x-p2.x)*(p1.x-p2.x) + (p1.y-p2.y)*(p1.y-p2.y);
} //返回A关于B的对称点C,即(A+C)/2=b
Point SymmetryPoint(Point A,Point B)
{
Point C;
C.x = *B.x-A.x;
C.y = *B.y-A.y;
return C;
} // 把矢量p旋转角度angle (弧度表示)
// angle > 0表示逆时针旋转
// angle < 0表示顺时针旋转
Point Rotate(Point p, double angle)
{
Point result;
result.x = p.x * cos(angle) - p.y * sin(angle);
result.y = p.x * sin(angle) + p.y * cos(angle);
return result;
} //得到向量p与x正半轴的夹角[0,2PI)
double GetAngle(Point p)
{
double tmp=atan2(p.y,p.x);
if(tmp<) tmp=*PI+tmp;
return tmp;
}
//得到两个向量之间的夹角[0,PI]
//若p1按顺时针转到p2的角小于PI(p1在p2的逆时针方向),则返回正数.否则返回负数.
double GetAngle(Point p1,Point p2)
{
double tmp = GetAngle(p1) - GetAngle(p2);
if( GT( tmp,PI) ) return -(*PI-tmp);
if( LEQ( tmp,-PI) ) return (tmp+*PI);
return tmp;
} // 判断二维平面上点是否在线段上
// 输入:任意点p,和任意直线L
// 输出:p在线段上返回1,否则返回0
bool OnSeg(Point p, Line L)
{
return ( ZERO( (L.p1 - p) * (L.p2 - p) ) &&
LEQ((p.x - L.p1.x)*(p.x - L.p2.x), ) &&
LEQ((p.y - L.p1.y)*(p.y - L.p2.y), ) );
} // 判断二维平面上点p是否在直线L上,在线段上返回1,否则返回0
bool OnLine(Point p, Line L)
{
return ZERO( (p - L.p1) * (L.p2 - L.p1) );
} bool OnCir(Point p,Circle cir)
{
return EQ( (p.x-cir.c.x)*(p.x-cir.c.x)+(p.y-cir.c.y)*(p.y-cir.c.y),cir.r*cir.r );
} //得到点p到直线L的距离,并返回p到直直线L的最近点rep
double PointToLine(Point p,Line L,Point& rep)
{
if(L.p1==L.p2)
{
rep=L.p1;
return Dis(p,L.p1);
}
Point a,b;
a = L.p2-L.p1;
b = p-L.p1;
double dis12 = Dis(L.p1,L.p2);
double dis = ( fabs(a*b) )/dis12; double k = (a&b)/(Norm(a)*dis12) ;
rep.x = L.p1.x + k*(L.p2.x-L.p1.x);
rep.y = L.p1.y + k*(L.p2.y-L.p1.y); return dis;
} //得到点P到线段L的距离,并放回p到线段L的最近点rep
double PointToSeg(Point P, Line L,Point& rep)
{
if(L.p1 == L.p2)
{
rep = L.p1;
return Dis(rep,P);//如果线段是一个点,返回这个点。
}
Point result;
double a, b, t; a = L.p2.x - L.p1.x;
b = L.p2.y - L.p1.y;
t = ( (P.x - L.p1.x) * a + (P.y - L.p1.y) * b ) / (a * a + b * b);//线段上的投影 if ( GEQ(t, ) && LEQ(t, ) ) {
result.x = L.p1.x + a * t;//值得学习的由比例求坐标的方法。
result.y = L.p1.y + b * t;
} else {
if ( Norm(P - L.p1) < Norm(P - L.p2) ) {
result = L.p1;
} else {
result = L.p2;
}
}
return Dis(result, P);
} //返回点A关于直线L的对称点
Point SymmetryPonitToLine(Point A,Line L)
{
Point B;
PointToLine(A, L, B);//A在L上的投影
return SymmetryPoint(A, B);
} /*-------------------几何题面积计算(注意正负!)----------------------*/ // 根据三个顶点坐标计算三角形面积
// 面积的正负按照右手旋规则确定,向量AB->向量AC
double Area(Point A, Point B, Point C)
{
return ((B-A)*(C-A) / 2.0);
} // 根据三条边长计算三角形面积
double Area(double a, double b, double c)
{
double s = (a + b + c) / 2.0;
return sqrt(s * (s - a) * (s - b) * (s - c));
} //求圆的面积
double Area(Circle C)
{
return PI * C.r * C.r;
} // 计算多边形面积,复杂度:O(顶点数)
// 面积的正负按照右手旋规则确定,顺时针为负
double Area(Polygon _poly)
{
int nsize=_poly.size();
double area=;
for(int i=;i<nsize;i++)
{
area += _poly[i]*_poly[(i+)%nsize];
}
return area/2.0;
} //求两条直线之间的关系(二维)
//输入:两条不为点的直线
//输出:相交返回XIANGJIAO和交点p,平行返回PINGXING,共线返回GONGXIAN
int LineAndLine(Line L1,Line L2,Point &p)
{
Point px,py;
px = L1.p1 - L1.p2;
py = L2.p1 - L2.p2;
if( EQ(px*py,) )//平行或者共线
{
if( ZERO( (L2.p1-L1.p1)*py ) ) //共线
{
return GONGXIAN;
}
return PINXING;
} double xa,xb,xc,ya,yb,yc;
xa=(L1.p2.y-L1.p1.y); xb=(L1.p1.x-L1.p2.x); xc=(L1.p1.y*L1.p2.x-L1.p1.x*L1.p2.y);
ya=(L2.p2.y-L2.p1.y); yb=(L2.p1.x-L2.p2.x); yc=(L2.p1.y*L2.p2.x-L2.p1.x*L2.p2.y); p.y = (xa*yc-xc*ya)/(xb*ya-xa*yb);
p.x = (xb*yc-xc*yb)/(xa*yb-xb*ya); return XIANGJIAO;
} //判断两条线段是否相交,相交返回1
bool SegAndSeg(Line L1,Line L2)
{
return ( GEQ( max(L1.p1.x, L1.p2.x), min(L2.p1.x, L2.p2.x) ) &&
GEQ( max(L2.p1.x, L2.p2.x), min(L1.p1.x, L1.p2.x) ) &&
GEQ( max(L1.p1.y, L1.p2.y), min(L2.p1.y, L2.p2.y) ) &&
GEQ( max(L2.p1.y, L2.p2.y), min(L1.p1.y, L1.p2.y) ) &&
LEQ( ((L2.p1 - L1.p1) * (L1.p2 - L1.p1)) * ((L2.p2 - L1.p1) * (L1.p2 - L1.p1)), ) &&
LEQ( ((L1.p1 - L2.p1) * (L2.p2 - L2.p1)) * ((L1.p2 - L2.p1) * (L2.p2 - L2.p1)), ) );
} //求两条线段交点(二维)
//输入:两条不为点的直线
//输出:相交返回XIANGJIAO和交点p,相离返回XIANGLI,重叠返回CHONGDIE
int SegAndSeg(Line L1,Line L2,Point &p)
{ double signx,signy; //跨立实验
if( LEQ(signx=( ((L1.p2-L1.p1)*(L1.p1-L2.p1))*((L1.p2-L1.p1)*(L1.p1-L2.p2)) ),) &&
LEQ(signy=( ((L2.p2-L2.p1)*(L2.p1-L1.p1))*((L2.p2-L2.p1)*(L2.p1-L1.p2)) ),) )
{
if( ZERO(signx) && ZERO(signy) )
{
//线段共线
signx = min( max(L1.p1.x,L1.p2.x),max(L2.p1.x,L2.p2.x) )-
max( min(L1.p1.x,L1.p2.x),min(L2.p1.x,L2.p2.x) ); signy = min( max(L1.p1.y,L1.p2.y),max(L2.p1.y,L2.p2.y) )-
max( min(L1.p1.y,L1.p2.y),min(L2.p1.y,L2.p2.y) ); if( ZERO(signx) && ZERO(signy) ) //说明共线,且相交一点
{
if(L1.p1==L2.p1||L1.p1==L2.p2) p=L1.p1;
if(L1.p2==L2.p1||L1.p2==L2.p2) p=L1.p2;
return XIANGJIAO;
}
else if( GEQ(signx, ) && GEQ(signy, ) )
{
return CHONGDIE;//重叠
}
else
{
return XIANGLI;//相离
}
}
return LineAndLine(L1, L2, p);//转化为直线相交
}
return XIANGLI;//相离
} // 判断点p是否在简单多边形poly内, 多边形可以是凸的或凹的
// poly的顶点数目要大于等于3
// 返回值为:
// INSIDE -- 点在poly内
// BORDER -- 点在poly边界上
// OUTSIDE -- 点在poly外
int InPolygon(const Polygon poly, Point p)
{
int i, n, count;
Line ray, side; n = poly.size();
count = ;
ray.p1 = p;
ray.p2.y = p.y;
ray.p2.x = - INF;// 设定一个极大值 for (i = ; i < n; i++) {
side.p1 = poly[i];
side.p2 = poly[(i+)%n]; if( OnSeg(p, side) ) {
return BORDER;
}
// 如果side平行x轴则不作考虑
if ( EQ(side.p1.y, side.p2.y) ) {
continue;
}
if (OnSeg(side.p1, ray)) {
if ( GT(side.p1.y, side.p2.y) ) count++;
} else if (OnSeg(side.p2, ray)) {
if ( GT(side.p2.y, side.p1.y) ) count++;
} else if ( SegAndSeg(ray, side) ) {
count++;
}
}
return ((count % == ) ? INSIDE : OUTSIDE);
} //得到直线与圆的交点
int LineToCir(Line L,Circle R,Point p[])
{
if(L.p1 == L.p2)//当直线为1个点时
{
if( EQ( Dis(L.p1, R.c),R.r ) )
{
p[]=L.p1;
return ;
}
else return ;//相离
}
Point tp;//表示圆心在直线L上的投影。
double dis=PointToLine(R.c, L,tp );
if( LT(R.r, dis) )//相离
{
return ;
}
if( EQ(dis,R.r) )//相切
{
p[]=tp;
return ;
}
double len=sqrt(R.r*R.r-dis*dis);
Point onep=L.p2-L.p1;
double _t = len/Norm(onep); p[].x =tp.x + onep.x*_t;
p[].y =tp.y + onep.y*_t; onep=L.p1-L.p2;
p[].x =tp.x + onep.x*_t;
p[].y =tp.y + onep.y*_t; return ;
} //得到三角形外接圆
//注意:A,B,C三点不能共线
Circle OutCircle(Point A,Point B,Point C)
{
Circle tmp;
double a, b, c, c1, c2;
double xA, yA, xB, yB, xC, yC;
a = Dis(A, B);
b = Dis(B, C);
c = Dis(C, A);
//根据 S = a * b * c / R / 4;求半径 R
tmp.r = (a*b*c)/( fabs(Area(A,B,C)) *4.0);
xA = A.x;
yA = A.y;
xB = B.x;
yB = B.y;
xC = C.x;
yC = C.y;
c1 = (xA*xA+yA*yA - xB*xB-yB*yB) / ;
c2 = (xA*xA+yA*yA - xC*xC-yC*yC) / ;
tmp.c.x = (c1*(yA - yC)-c2*(yA - yB)) / ((xA - xB)*(yA - yC)-(xA - xC)*(yA - yB));
tmp.c.y = (c1*(xA - xC)-c2*(xA - xB)) / ((yA - yB)*(xA - xC)-(yA - yC)*(xA - xB));
return tmp;
} //得到三角形内切圆
//注意:A,B,C三点不能共线
Circle InCircle(Point A,Point B,Point C)
{
Circle rec;
double a=Dis(B,C);
double b=Dis(A,C);
double c=Dis(A,B);
rec.c.x = (a*A.x+b*B.x+c*C.x)/(a+b+c);
rec.c.y = (a*A.y+b*B.y+c*C.y)/(a+b+c);
rec.r = *fabs( Area(A,B,C) )/(a+b+c);
return rec;
} //得到两圆的面积并
double CirArea(Circle _c1,Circle _c2)
{
if(_c2.r<_c1.r) swap(_c1,_c2); //保证_c2的半径大
double d12 = Dis(_c1.c,_c2.c);
if( LEQ(_c1.r+_c2.r,d12) )//相离
{
return ;
}
if( LEQ(d12+_c1.r, _c2.r) )//包含
{
return Area(_c1);
}
//相交
double _area=;
_area -= 2.0*Area(_c1.r,_c2.r,d12);
double ang1 = acos( (d12*d12+_c1.r*_c1.r-_c2.r*_c2.r) / (*d12*_c1.r) );
double ang2 = acos( (d12*d12+_c2.r*_c2.r-_c1.r*_c1.r) / (*d12*_c2.r) );
_area += ang1*_c1.r*_c1.r+ang2*_c2.r*_c2.r;
return _area;
} //得到两个圆的交点p[2]
//返回值为交点数,-1为两圆重叠。
int CirAndCir(Circle _c1,Circle _c2,Point p[])
{
if(_c2.r < _c1.r) swap(_c1,_c2); //保证_c2的半径大
double d12 = Dis(_c1.c,_c2.c);
if( LT(_c1.r+_c2.r,d12) )//相离
{
return ;
}
if( LT(d12+_c1.r, _c2.r) )//包含
{
return ;
}
if(_c1.c == _c2.c)//两个圆重叠
{
return -;
}
Point u,v;
double t;
double r1=_c1.r,r2=_c2.r; t=( +(r1*r1-r2*r2)/(Dis(_c1.c,_c2.c)*Dis(_c1.c,_c2.c)) ) /;
u.x = _c1.c.x + (_c2.c.x-_c1.c.x)*t;
u.y = _c1.c.y + (_c2.c.y-_c1.c.y)*t; v.x = u.x + _c1.c.y - _c2.c.y;
v.y = u.y - _c1.c.x + _c2.c.x; Line _l(u,v);
return LineToCir(_l,_c1,p);
} //求凸包Graham-Scan(GS)算法,复杂度nlog(n),内附两种模式,最小点集凸包,与最大点集凸包。
//调用GetConvex_GS(Point ps[],int pn,Point cx[],int &cxn)
//其中ps是输入的点集,pn为ps的大小,cx为返回的凸包集,cxn表示凸包的大小。
//注意:pn必须>=3,下标都是从0开始,返回的凸包集为逆时针。且如果点带标号,一样处理。 int GScmp(Point a,Point b)
{
double _tmp=a*b;
Point zero;
zero.x=;
zero.y=;
if( ZERO(_tmp) )
{
return Dis2(a,zero)>Dis2(b,zero);
}
return _tmp > ;
} void GetConvex_GS(Point ps[],int pn,Point cx[],int &cxn)
{
Polygon pg; pg.clear();
//先找出最下面,如果有相同的找最靠左,也就找y轴最小的,然后y相同时选x最小。
Point minp=ps[];
for(int i=;i<pn;i++)
{
if( ps[i].y < minp.y )
{
minp = ps[i];
}
else if(EQ(ps[i].y, minp.y) && ps[i].x < minp.x)
{
minp = ps[i];
}
} for(int i=;i<pn;i++)
{
ps[i].x -= minp.x;
ps[i].y -= minp.y;
pg.push_back( ps[i] );
} //排序
sort(pg.begin(),pg.end(),GScmp); //在这一步,除去与minp共线的点。
long int pgsize=pg.size();
int pgcnt=;
for(int i=;i<pgsize;i++)
{
if( !ZERO(pg[i]*pg[pgcnt-]) )
{
pg[ pgcnt++ ] = pg[i];
}
} cxn = ;
cx[ cxn++ ] = minp; if( !(ZERO(pg[].x) && ZERO(pg[].y)) )//不为一点时
{
pg[].x += minp.x;
pg[].y += minp.y;
cx[ cxn++ ] = pg[];//必须保存id for(int i=;i < pgcnt;i++)
{
pg[i].x += minp.x;
pg[i].y += minp.y; double _tmp = (cx[cxn-]-cx[cxn-])*(pg[i]-cx[cxn-]);
// 无法处理重复点!
// nice !
while( LEQ(_tmp, ) )
{
cxn--;
//if(cxn==1) break;//只剩下一个的时候,退出
_tmp = (cx[cxn-]-cx[cxn-])*(pg[i]-cx[cxn-]);
}
cx[ cxn++ ] = pg[i];
}
}
//已经找到了,最小凸包集,且为逆时针排序。
/*
//接下来步骤为找出所有在凸包边界上的点,并按逆时针排序。
sort(ps,ps+pn,GScmp);
int cxn1=0;
int tj=0;
for(int i=0;i<pn;i++)
{
ps[i].x += minp.x;
ps[i].y += minp.y;
Line l(cx[tj],cx[(tj+1)%cxn]);
if( OnSeg(ps[i], l) )
{
ps[ cxn1++ ] = ps[i];
continue;
}
if( tj+1<cxn && GEQ( (cx[tj+1]-minp)*(ps[i]-minp),0 ) )
{
tj++;
}
l.p1 = cx[ tj ];
l.p2 = cx[ (tj+1)%cxn ];
if(OnSeg(ps[i], l)) ps[cxn1++]=ps[i];
}
cxn=cxn1;
for(int i=0;i<cxn1;i++)
cx[i]=ps[i];
//接下来的步骤是,将凸包点集调整为逆时针,其实只需要调整斜率最大的一条边。
tj=1;
Line l(minp,cx[0]);
while(tj<cxn && OnSeg(cx[tj], l)) tj++;
tj--;
for(int i=0;i<=tj;i++)
cx[i] = ps[tj-i];
////////////////////////////////////
*/
} /*---------------------代码区---------------------------*/ //what the fuck
double ans; //返回两条线段的最短距离
double Dis(Line l1,Line l2)
{
Point p;
return min( min(PointToSeg(l1.p1, l2,p),PointToSeg(l1.p2, l2, p))
,min(PointToSeg(l2.p1, l1,p),PointToSeg(l2.p2, l1, p)) );
} void CirAndCut(Point psn[],int n,Point psm[],int m)
{
int nid=,mid=; for(int i=;i<n;i++)
if(psn[i].y>psn[nid].y)
{
nid=i;
}
for(int i=;i<m;i++)
if(psm[i].y<psm[mid].y)
{
mid=i;
}
//找到点集n中最上点,m中的最下点。
//l 为水平向右的向量
for(int ii=;ii<n+m;ii++)
{
//第一步判断谁先 滚起来
Point nextn,nextm;
nextn = psn[(nid+)%n];
nextm = psm[(mid+)%m]; if( (nextn-psn[nid])*(psm[mid]-nextm)> )
{
//n先滚
nid = (nid+)%n;
}
else
{
mid= (mid+)%m;
}
//这里就可以得到对踵点
Line l1,l2;
l1.p1 = psn[nid];
l1.p2 = psn[ (nid-+n)%n ];
l2.p1 = psm[mid];
l2.p2 = psm[ (mid-+m)%m ];
ans = min(ans,Dis(l1, l2));
}
} Point psn[],psm[]; int main(int argc, const char * argv[]) {
int n,m;
while( scanf("%d%d",&n,&m) && (n+m) )
{
for(int i=;i<n;i++)
psn[i].read();
for(int i=;i<m;i++)
psm[i].read();
Point cn[],cm[];
int cntn,cntm;
GetConvex_GS(psn, n, cn, cntn);
GetConvex_GS(psm, m, cm, cntm);
ans = INF;
/*
if(cntn<=3||cntm<=3)
{
for(int i=0;i<cntn;i++)
{
for(int j=0;j<cntm;j++)
{
Line l(cm[j],cm[(j+1)%cntm]);
Point p;
ans = min(ans,PointToSeg(cn[i], l, p));
}
}
for(int i=0;i<cntm;i++)
{
for(int j=0;j<cntn;j++)
{
Line l(cn[j],cn[(j+1)%cntn]);
Point p;
ans = min(ans,PointToSeg(cm[i], l, p));
}
}
}
else */ CirAndCut(cn,cntn,cm,cntm);
printf("%.6lf\n",ans);
}
return ;
} /*
5 5
1 -1
2 -1
3 -1
2 -2
3 -2
-1 1
-2 1
-3 1
-2 2
-3 2
5 5
-1 1
-2 1
-3 1
-2 2
-3 2
1 -1
2 -1
3 -1
2 -2
3 -2
*/

旋转卡壳求两个凸包最近距离poj3608的更多相关文章

  1. 「POJ-3608」Bridge Across Islands (旋转卡壳--求两凸包距离)

    题目链接 POJ-3608 Bridge Across Islands 题意 依次按逆时针方向给出凸包,在两个凸包小岛之间造桥,求最小距离. 题解 旋转卡壳的应用之一:求两凸包的最近距离. 找到凸包 ...

  2. POJ3608(旋转卡壳--求两凸包的最近点对距离)

    题目:Bridge Across Islands 分析:以下内容来自:http://blog.csdn.net/acmaker/article/details/3178696 考虑如下的算法, 算法的 ...

  3. POJ 3608 Bridge Across Islands(旋转卡壳,两凸包最短距离)

    Bridge Across Islands Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7202   Accepted:  ...

  4. poj 2187 Beauty Contest , 旋转卡壳求凸包的直径的平方

    旋转卡壳求凸包的直径的平方 板子题 #include<cstdio> #include<vector> #include<cmath> #include<al ...

  5. UVa 1453 - Squares 旋转卡壳求凸包直径

    旋转卡壳求凸包直径. 参考:http://www.cppblog.com/staryjy/archive/2010/09/25/101412.html #include <cstdio> ...

  6. POJ2187 旋转卡壳 求最长直径

    给定平面上的一些散点集,求最远两点距离的平方值. 题解: 旋转卡壳求出凸包,然后根据单调性,求出最远两点的最大距离 #pragma GCC optimize(2) #pragma G++ optimi ...

  7. POJ 2079 Triangle 旋转卡壳求最大三角形

    求点集中面积最大的三角形...显然这个三角形在凸包上... 但是旋转卡壳一般都是一个点卡另一个点...这种要求三角形的情况就要枚举底边的两个点 卡另一个点了... 随着底边点的递增, 最大点显然是在以 ...

  8. [hdu5251]矩形面积 旋转卡壳求最小矩形覆盖

    旋转卡壳求最小矩形覆盖的模板题. 因为最小矩形必定与凸包的一条边平行,则枚举凸包的边,通过旋转卡壳的思想去找到其他3个点,构成矩形,求出最小面积即可. #include<cstdio> # ...

  9. GPS(2)关于位置的3个示例,实时获取GPS定位数据,求两个经纬点距离,邻近某个区域圆时警告

    实时获取GPS定位数据 import android.app.Activity; import android.content.Context; import android.location.Loc ...

随机推荐

  1. python 常用的模块(base64)转

    Base64是一种用64个字符来表示任意二进制数据的方法. 用记事本打开exe.jpg.pdf这些文件时,我们都会看到一大堆乱码,因为二进制文件包含很多无法显示和打印的字符,所以,如果要让记事本这样的 ...

  2. python核心编程学习记录之Web编程

    cgi未完待续

  3. 2017.5.9 java多线程总结

    参考来自:http://www.cnblogs.com/lwbqqyumidi/p/3804883.html http://blog.csdn.net/gf771115/article/details ...

  4. 20160208.CCPP体系具体解释(0018天)

    程序片段(01):main.c 内容概要:PointWithOutInit #include <stdio.h> #include <stdlib.h> //01.野指针具体解 ...

  5. Transportation poj1040

    Ruratania is just entering capitalism and is establishing new enterprising activities in many fields ...

  6. Linux非阻塞IO(二)网络编程中非阻塞IO与IO复用模型结合

    上文描述了最简易的非阻塞IO,采用的是轮询的方式,这节我们使用IO复用模型.   阻塞IO   过去我们使用IO复用与阻塞IO结合的时候,IO复用模型起到的作用是并发监听多个fd. 以简单的回射服务器 ...

  7. python——内置对象

    python的内置对象 对象类型 常量示例/用法 Number(数字) 3.14159, 1234, 999L 3+4j String(字符串) 'spam', "guido's" ...

  8. DNS、bind 953端口

    1.953端口是rndc 的端口 2.rndc是监控bind的统计数据用的,同时不需要为了更新某个zone而重启bind 3.输入rndc ,如果ok的话,是这样的 4.看到第一条语句了没. 不需要重 ...

  9. android推断手机是否root

    关于推断手机是否已经root的方法.假设app有一些特殊功能须要root权限,则须要推断是否root. 比方一些市场下载完app后自己主动安装. /** * @author Kevin Kowalew ...

  10. linux标准输入输出错误输出

    Linux Shell 环境中支持输入输出重定向,用符号"<"和">"来表示.0.1和2分别表示标准输入.标准输出和标准错误信息输出,可以用来指定需 ...