zoukankan      html  css  js  c++  java
  • poj1556

    题目大意:起点坐标(0,5),终点坐标(10,5),在这两点之间有着n道墙,每道墙有两个门

    求起点到终点的最短距离

    思路:构图,floyed算法,此题主要是判断两点是否连通,及判断线段相交,我通过题目给出的数据构造了3*n条线段

    因为每一道墙2个门,及相对的有3条线段,用两点在他们之间的所有线段都判断一次是否相交

    代码如下:

    #include <iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    using namespace std;
    const int maxs = 100;
    const float INF = 0x3f3f3f3f;
    const float eps = 1e-6;
    typedef struct
    {
        float x;
        float y;
    }Point;
    
    typedef struct
    {
        Point s;
        Point e;
    }Line;
    Point points[maxs];//points[0]起点,points[nums-1]终点
    Line lines[maxs];//线段标号从1开始
    float X[maxs];
    int N,nums,counts;//N:墙的数目,nums:点的总个数,counts:线段的条数-障碍物
    float A[maxs][maxs];
    
    void getLine()
    {
        //把除起点和终点外的所有点构成线段,每一道墙3条线段
        Point temp1,temp2;
        int k;
        for(int i=1;i<=N*3;i=i+3)
        {
            k=i/3+1;
            temp1.x=X[k];temp1.y=0;
            temp2.x=X[k];temp2.y=10;
            lines[i].s=temp1;
            lines[i].e=points[k*4-3];
            lines[i+1].s=points[k*4-2];
            lines[i+1].e=points[k*4-1];
            lines[i+2].s=points[k*4-0];
            lines[i+2].e=temp2;
        }
        counts=N*3;
    }
    float dis(Point point1,Point point2)
    {
        float d1 = point1.x-point2.x;
        float d2 = point1.y-point2.y;
        return sqrt(d1*d1+d2*d2);
    }
    bool isCross(Point a,Point b,Line line)
    {
        //该线段不在a,b两点之间,不相交
        if(line.s.x<=a.x||line.s.x>=b.x)
            return false;
        //交点已知横坐标,根据横坐标算出交点纵坐标
        float x = line.e.x;
        float k = (a.y-b.y)/(a.x-b.x);
        float y = k*(x-a.x)+a.y;
        if(y-line.s.y>eps&&line.e.y-y>eps)
            return true;
        return false;
    
    }
    //判断两点之间是否可以连通,连通true
    bool judge(Point a,Point b)
    {
        //找出所有在这两点之间的线段,线段的横坐标大于起点,小于终点
        //a的横坐标比b的小,如果相等说明在同一道墙上,先假定相交后面再判断
        if(a.x==b.x)
            return false;
        int i=1,j=counts;
    //    while(lines[i].s.x<=a.x&&i<counts) i=i+3;
    //    while(lines[j].s.x>=b.x&&j>1) j=j-3;
        for(int k=i;k<=j;k++)
            if(isCross(a,b,lines[k]))
                return false;
        return true;
    }
    void floyed()
    {
        for(int k=0;k<nums;k++)
            for(int i=0;i<nums;i++)
                for(int j=0;j<nums;j++)
                    if(A[i][j]>A[i][k]+A[k][j])
                        A[i][j]=A[i][k]+A[k][j];
    }
    int main()
    {
        //freopen("in.txt","r",stdin);
        while(scanf("%d",&N)!=EOF&&N!=-1)
        {
            nums=0;
            memset(points,0,sizeof(points));
            memset(lines,0,sizeof(lines));
            points[nums].x=0;points[nums].y=5;
            for(int i=1;i<=N;i++)
            {
                scanf("%f",&X[i]);
                for(int j=1;j<=4;j++)
                {
                    points[++nums].x=X[i];
                    scanf("%f",&points[nums].y);
                }
            }
            points[++nums].x=10;points[nums].y=5;
            nums++;
            //初始化距离
            for(int i=0;i<nums;i++)
                for(int j=0;j<nums;j++)
                    if(i==j)
                        A[i][j]=0;
                    else
                        A[i][j]=INF;
            //初始化线段
            getLine();
            //对于起点的判断
            for(int i=1;i<nums;i++)
                if(judge(points[0],points[i]))
                {
                    A[0][i]=dis(points[0],points[i]);
                    A[i][0]=dis(points[0],points[i]);
                }
            //对于其它任意不在同一道墙间的点判断
            for(int i=1;i<nums;i++)
            {
                for(int j=i+1;j<nums;j++)
                {
                    if(judge(points[i],points[j]))
                    {
                        A[i][j]=dis(points[i],points[j]);
                        A[j][i]=dis(points[i],points[j]);
                    }
                }
            }
            for(int i=1;i<=N;i++)
            {
                //1-2连通,3-4连通,以此类推
                int index1 = i*4-3;
                int index2 = i*4-2;
                int index3 = i*4-1;
                int index4 = i*4;
                A[index1][index2]=A[index2][index1]=dis(points[index1],points[index2]);
                A[index3][index4]=A[index4][index3]=dis(points[index3],points[index4]);
            }
            floyed();
            printf("%.2f
    ",A[0][nums-1]);
        }
        return 0;
    }
  • 相关阅读:
    Java JMX 监管
    Spring Boot REST(一)核心接口
    JSR 规范目录
    【平衡树】宠物收养所 HNOI 2004
    【树型DP】叶子的颜色 OUROJ 1698
    【匈牙利匹配】无题II HDU2236
    【贪心】Communication System POJ 1018
    【贪心】Moving Tables POJ 1083
    Calling Extraterrestrial Intelligence Again POJ 1411
    【贪心】Allowance POJ 3040
  • 原文地址:https://www.cnblogs.com/wt20/p/5738633.html
Copyright © 2011-2022 走看看