• [poj][3608][Bridge Across Islands]


    题目:http://poj.org/problem?id=3608

    View Code
    #include <stdio.h>
    #include <math.h>
    #include <string.h>
    #include <algorithm>
    
    #define clr(a,b) memset(a,b,sizeof(a))
    #define sqr(x) ((x)*(x))
    using namespace std;
    
    const double eps = 1e-8;
    const double pi = acos(-1.0);
    const int inf = 0x3f3f3f3f;
    const int N = 10000+10;
    
    int dcmp(double x){
        if (x < -eps) return -1;
        else return x > eps;
    }
    
    struct cpoint
    {
        double x, y;
        cpoint(){}
        cpoint(double x, double y):x(x), y(y){}
        void get() { scanf("%lf%lf", &x, &y); }
        bool operator == (const cpoint& u)const{
            return dcmp(x - u.x) == 0 && dcmp(y - u.y) == 0;
        }
    };
    
    double cross(cpoint o, cpoint p, cpoint q){
        return (p.x-o.x)*(q.y-o.y)-(q.x-o.x)*(p.y-o.y);
    }
    double dot(cpoint o, cpoint p, cpoint q){
        return (p.x-o.x)*(q.x-o.x)+(p.y-o.y)*(q.y-o.y);
    }
    double dis(cpoint p, cpoint q){
        return sqrt(sqr(p.x-q.x) + sqr(p.y-q.y));
    }
    double dissqr(cpoint p, cpoint q){
        return sqr(p.x-q.x) + sqr(p.y-q.y);
    }
    bool PointOnSegment(cpoint p0, cpoint p1, cpoint p2){
        return dcmp(cross(p0, p1, p2)) == 0 && dcmp(dot(p0, p1, p2)) <= 0;
    }
    double PointToLine(cpoint p0, cpoint p1, cpoint p2, cpoint &cp){
        double d = dis(p1, p2);
        double s = cross(p1, p2, p0) / d;
        cp.x = p0.x + s * (p2.y - p1.y) / d;
        cp.y = p0.y - s * (p2.x - p1.x) / d;
        return fabs(s);
    }
    cpoint bp;
    int PolarCmp(const cpoint &p1, const cpoint &p2){
        int u = dcmp(cross(bp, p1, p2));
        return u > 0 || (u==0 && dcmp(dissqr(bp, p1)-dissqr(bp, p2))<0);
    }
    void graham(cpoint pin[], int n, cpoint ch[], int &m){
        int i, j, k, u, v;
        memcpy(ch, pin, n*sizeof(cpoint));
        for (i=k=0; i<n; i++){
            u = dcmp(ch[i].x - ch[k].x);
            v = dcmp(ch[i].y - ch[k].y);
            if (v < 0 || (v==0 && u<0)) k = i;
        }
        bp = ch[k];
        sort(ch, ch+n, PolarCmp);
        n = unique(ch, ch+n) - ch;
        if (n <= 1) { m = n; return ; }
        if (dcmp(cross(ch[0],ch[1],ch[n-1]))==0){
            m = 2; ch[1] = ch[n-1]; return ;
        }
        ch[n++] = ch[0];
        for (i=1, j=2; j<n; j++){
            while (i>0 && dcmp(cross(ch[i-1], ch[i], ch[j]))<=0)i--;
            ch[++i] = ch[j];
        }
        m = i;
    }
    double PointToSeg(cpoint p0, cpoint p1, cpoint p2){
        cpoint cp;
        double d = PointToLine(p0, p1, p2, cp);
        if (PointOnSegment(cp, p1, p2)) return d;
        else return min(dis(p0, p1), dis(p0, p2));
    }
    double DisPallSeg(cpoint p0, cpoint p1, cpoint p2, cpoint p3){
        return min(min(PointToSeg(p0, p2, p3), PointToSeg(p1, p2, p3)),
                   min(PointToSeg(p2, p0, p1), PointToSeg(p3, p0, p1)));
    }
    void anticlockwise(cpoint cp[], int n){
        for (int i=0; i<n-2; i++){
            double t = cross(cp[i], cp[i+1], cp[i+2]);
            if (dcmp(t) > 0) return ;
            if (dcmp(t) < 0) { reverse(cp, cp+n); return ; }
        }
    }
    double rotating(cpoint ch1[], int n, cpoint ch2[], int m){
        int p = 0, q = 0;
        for (int i=0; i<n; i++)
            if (dcmp(ch1[i].y - ch1[p].y) < 0)
                p = i;
        for (int i=0; i<m; i++)
            if (dcmp(ch2[i].y - ch2[q]. y) > 0)
                q = i;
        ch1[n] = ch1[0], ch2[m] = ch2[0];
        double tmp, res = 1e99;
        for (int i=0; i<n; i++){
            while ((tmp = cross(ch1[p],ch1[p+1],ch2[q+1])-
                cross(ch1[p],ch1[p+1],ch2[q])) > eps)
                q = (q + 1) % m;
            if (dcmp(tmp) < 0) res = min(res, PointToSeg(ch2[q], ch1[p], ch1[p+1]));
            else res = min(res, DisPallSeg(ch1[p], ch1[p+1], ch2[q], ch2[q+1]));
            p = (p + 1) % m;
        }
        return res;
    }
    
    void solve(cpoint ch1[], int n, cpoint ch2[], int m){
        anticlockwise(ch1, n);
        anticlockwise(ch2, m);
        double ans = min(rotating(ch1, n, ch2, m), rotating(ch2, m, ch1, n));
        printf("%.5f\n", ans);
    }
    cpoint p[N], q[N];
    int main()
    {
        //freopen("D:/a.txt", "r", stdin);
        int n, m;
        while (~scanf("%d%d", &n, &m))
        {
            if (n==0 && m==0) break;
            for (int i=0; i<n; i++) p[i].get();
            for (int i=0; i<m; i++) q[i].get();
            solve(p, n, q, m);
        }
        return 0;
    }
  • 相关阅读:
    Codeforces Round #104 (Div. 1) C. Lucky Subsequence
    UVALive 4848 Tour Belt
    ...
    HDU4609 计数问题+FFT
    hdu6129 Just Do It!
    hdu6133 Army Formations 线段树合并
    迭代FFT
    第二类Stirling数
    project euler113
    HBase 常用shell命令
  • 原文地址:https://www.cnblogs.com/nigel0913/p/2586807.html
Copyright © 2020-2023  润新知