码迷,mamicode.com
首页 > 其他好文 > 详细

poj1556

时间:2016-08-04 23:15:38      阅读:253      评论:0      收藏:0      [点我收藏+]

标签:

题目大意:起点坐标(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\n",A[0][nums-1]);
    }
    return 0;
}

 

poj1556

标签:

原文地址:http://www.cnblogs.com/wt20/p/5738633.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!