• poj 1556 题解


    题意:如图,大概猜的到了?最多18面墙,每面墙上两个门,从(0,5)走到(10,5)的最短距离,保留两位小数

    题解:这道题非常贴心地按序给出墙的坐标,把每个端点当做图里面的一个节点,用O(n3)时间判断每两点之间是否能连边,判断方法为判断直线与线段是否相交(事实上是两个线段,但在这道题里面用直线交线段即可),跑一个最短路即可(既然已经到了三次方级别,干脆写了最短的Floyd)

    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
    using namespace std;
    
    #define rep(i,a,b) for (int i=a;i<=b;++i)
    
    const double eps=1e-7;
    
    struct point{
        double x,y;
        point(){}
        point (double a,double b): x(a),y(b) {}
    
        friend point operator + (const point &a,const point &b){
            return point(a.x+b.x,a.y+b.y);
        }
    
        friend point operator - (const point &a,const point &b){
            return point(a.x-b.x,a.y-b.y);
        }
    
        friend point operator * (const double &r,const point &a){
            return point(r*a.x,r*a.y);
        }
    
        friend bool operator == (const point &a,const point &b){
            return (abs(a.x-b.x)<eps && abs(a.y-b.y)<eps);
        }
    
        double norm(){
            return sqrt(x*x+y*y);
        }
    };
    
    inline double det(point a,point b) {return a.x*b.y-a.y*b.x;}
    inline double dot(point a,point b) {return a.x*b.x+a.y*b.y;}
    inline double dist(point a,point b) {return (a-b).norm();}
    
    inline bool line_cross_segment(point s,point t,point a,point b)
    {
        return !(det(s-a,t-a)*det(s-b,t-b)>eps);
    }
    
    int n,m;
    point s[1000];
    double dis[1000][1000],x,y;
    
    bool ok(int a,int b)
    {
        point ts=s[a],tt=s[b];
        if (a/4+(a%4!=0)==b/4+(b%4!=0)) return false;
        rep(i,a/4+(a%4!=0)+1,b/4+(b%4!=0)-1)
        {
            if (!line_cross_segment(ts,tt,s[(i-1)*4+1],s[(i-1)*4+2]) && !(line_cross_segment(ts,tt,s[(i-1)*4+3],s[(i-1)*4+4]))) return false;
        }
        return true;
    }
    
    int main()
    {
        while (~scanf("%d",&n))
        {
            if (n==-1) break;
            m=4*n+1;
            rep(i,0,m)
                rep(j,0,m) dis[i][j]=1000000;
            rep(i,0,m) dis[i][i]=0;
            s[0]=point(0,5);
            rep(i,1,n)
            {
                scanf("%lf",&x);
                rep(j,1,4)
                    {
                        scanf("%lf",&y);
                        s[4*(i-1)+j]=point(x,y);
                    }
    
            }
            s[m]=point(10,5);
            rep(i,0,m)
                rep(j,i+1,m)
                    if (ok(i,j)) dis[i][j]=dist(s[i],s[j]);
            rep(i,0,m)
                rep(j,0,m)
                    rep(k,0,m)
                        dis[j][k]=min(dis[j][k],dis[j][i]+dis[i][k]);
            printf("%.2f
    ",dis[0][m]);
        }
    }
  • 相关阅读:
    bug
    UIFont
    OC
    iOS 之 多线程一
    OC 之 const
    我的读书单
    算法之回文数判断
    排序算法 之 一
    isEqual
    xcode 必用插件二
  • 原文地址:https://www.cnblogs.com/terra/p/7008247.html
Copyright © 2020-2023  润新知