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;
    }
  • 相关阅读:
    Linux学习笔记 -- stdin/stdout 重定向
    Linux学习笔记
    使用 maven 构建 SpringMVC
    Linux学习笔记
    (转)Tomcat 启动后 “闪退”
    解决: Project facet Java version 1.8 is not supported
    由 MySQL server 和 mysql-connector 版本的不匹配引发的一场惊魂
    Adobe Acrobat 不能打开在线pdf。Adobe Acrobat 应用程序正在被终止,因为内存错误
    收缩数据库日志文件
    android基站定位程序获取地理位置
  • 原文地址:https://www.cnblogs.com/wt20/p/5738633.html
Copyright © 2011-2022 走看看