首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 其他教程 > 操作系统 >

poj 3608 Bridge Across Islands(两凸包前不久距离)

2013-09-06 
poj 3608 Bridge Across Islands(两凸包最近距离)很裸的题,还是用旋转卡壳的方法。输入点的顺序就是逆时针

poj 3608 Bridge Across Islands(两凸包最近距离)

很裸的题,还是用旋转卡壳的方法。输入点的顺序就是逆时针输入了。

#include<algorithm>#include<iostream>#include<cstring>#include<cstdlib>#include<fstream>#include<sstream>#include<vector>#include<string>#include<cstdio>#include<bitset>#include<stack>#include<queue>#include<cmath>#include<map>#include<set>#define FF(i, a, b) for(int i=a; i<b; i++)#define FD(i, a, b) for(int i=a; i>=b; i--)#define REP(i, n) for(int i=0; i<n; i++)#define CLR(a, b) memset(a, b, sizeof(a))#define PB push_back#define LL long long#define eps 1e-10#define debug puts("**debug**")using namespace std;struct Point{    double x, y;    Point(double x=0, double y=0):x(x), y(y){}};typedef Point Vector;Vector operator + (Vector a, Vector b) { return Vector(a.x+b.x, a.y+b.y); }Vector operator - (Vector a, Vector b) { return Vector(a.x-b.x, a.y-b.y); }Vector operator * (Vector a, double p) { return Vector(a.x*p, a.y*p); }Vector operator / (Vector a, double p) { return Vector(a.x/p, a.y/p); }bool operator < (const Point& a, const Point& b){    return a.x < b.x || (a.x == b.x && a.y <b.y);}int dcmp(double x){    if(fabs(x) < eps) return 0; return x < 0 ? -1 : 1;}bool operator == (const Point& a, const Point& b){    return dcmp(a.x-b.x) == 0 && dcmp(a.y-b.y) == 0;}double Dot(Vector a, Vector b) { return a.x*b.x + a.y*b.y; }double Length(Vector a) { return sqrt(Dot(a, a)); }double Cross(Vector a, Vector b) { return a.x*b.y - a.y*b.x; }//如果输入点是顺时针输入,转为逆时针顺序void anticolockwise(Point *ch,int len){    for(int i=0;i<len-2;i++)    {        double tmp = Cross(ch[i]-ch[i+2], ch[i+1]-ch[i+2]);        if(tmp > eps)            return;        else if(tmp < -eps)        {            reverse(ch, ch+len);            return;        }    }}//点p到直线ab的距离double DistanceToSegment(Point p, Point a, Point b){    if(a == b) return Length(p-a);    Vector v1 = b-a, v2 = p-a, v3 = p-b;    if(dcmp(Dot(v1, v2)) < 0) return Length(v2);    else if(dcmp(Dot(v1, v3)) > 0) return Length(v3);    else return fabs(Cross(v1, v2)) / Length(v1);}double dis_pair_seg(Point p1, Point p2, Point p3, Point p4){    return min(min(DistanceToSegment(p1, p3, p4), DistanceToSegment(p2, p3, p4)),     min(DistanceToSegment(p3, p1, p2), DistanceToSegment(p4, p1, p2)));}double RC_Distance(Point *ch1, Point *ch2, int n, int m){    int q=0, p=0;    REP(i, n) if(ch1[i].y-ch1[p].y < -eps) p=i;    REP(i, m) if(ch2[i].y-ch2[q].y > eps) q=i;    ch1[n]=ch1[0];  ch2[m]=ch2[0];    double tmp, ans=1e100;    REP(i, n)    {        while((tmp = Cross(ch1[p+1]-ch1[p], ch2[q+1]-ch1[p]) - Cross(ch1[p+1]-ch1[p], ch2[q]- ch1[p])) > eps)            q=(q+1)%m;        if(tmp < -eps) ans = min(ans,DistanceToSegment(ch2[q],ch1[p],ch1[p+1]));        else ans = min(ans,dis_pair_seg(ch1[p],ch1[p+1],ch2[q],ch2[q+1]));        p=(p+1)%n;    }    return ans;}int n, m;Point ch1[10001], ch2[10001];int main(){    while(scanf("%d%d", &n, &m), n+m)    {        REP(i, n) scanf("%lf%lf", &ch1[i].x, &ch1[i].y);        REP(i, m) scanf("%lf%lf", &ch2[i].x, &ch2[i].y);        printf("%.5f\n", min(RC_Distance(ch1, ch2, n, m), RC_Distance(ch2, ch1, m, n)));    }    return 0;}


热点排行