POJ 1556-The Doors

The Doors

Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 10545   Accepted: 3924

Description

You are to find the length of the shortest path through a chamber containing obstructing walls. The chamber will always have sides at x = 0, x = 10, y = 0, and y = 10. The initial and final points of the path are always (0, 5) and (10, 5). There will also be from 0 to 18 vertical walls inside the chamber, each with two doorways. The figure below illustrates such a chamber and also shows the path of minimal length. 

Input

The input data for the illustrated chamber would appear as follows. 


4 2 7 8 9 
7 3 4.5 6 7 

The first line contains the number of interior walls. Then there is a line for each such wall, containing five real numbers. The first number is the x coordinate of the wall (0 < x < 10), and the remaining four are the y coordinates of the ends of the doorways in that wall. The x coordinates of the walls are in increasing order, and within each line the y coordinates are in increasing order. The input file will contain at least one such set of data. The end of the data comes when the number of walls is -1. 

Output

The output should contain one line of output for each chamber. The line should contain the minimal path length rounded to two decimal places past the decimal point, and always showing the two decimal places past the decimal point. The line should contain no blanks.

Sample Input

1
5 4 6 7 8
2
4 2 7 8 9
7 3 4.5 6 7
-1

Sample Output

10.00
10.06

Source

Mid-Central USA 1996

题目大意:给你一个坐标轴(x:0-10,y:0-10,现在这个坐标轴内有不超过18堵墙,每堵墙上面有两个门,问你从(0,5)到(10,5)的最短距离是多少?

思路:枚举每个点到其它点的距离,如果这两个点之间有墙,则不进行计算,最后最短路跑一边,得出答案。

代码:

/*
大意:给你一个图,图中有很多的墙,墙上有门
问你从(0,5)到(10,5)的最短距离
思路:把(0,5)到每个门(中间没有墙挡住)的距离算出来,
使用最短路算法,随便哪个都行,数据比较小
*/
#include<map>
#include<stack>
#include<queue>
#include<string>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;
#define ll long long
#define ul unsigned long long
#define bug printf("mmp\n");
#define inf 0x3f3f3f3f
#define esp 1e-4
#define mm(a,b) memset(a,b,sizeof(a))
#define T()int test,q=1,tt;scanf("%d",&test),tt=test;while(test--)
const int N=1e2+10;
const int maxn=1e6+100;
const int mod=1000000007;
struct point
{
    double x,y;
} p[N];
struct line
{
    point st,ed;
    double k,b;
} l[N];
int sign(double x)
{
    if(fabs(x)<esp)
        return 0;
    return x>0?1:-1;
}
double dis(point a,point b)
{
    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
double mult(point a,point b,point c)
{
    return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y);
}
bool judge(line l1,line l2)
{
    int a1=sign(max(l1.st.x,l1.ed.x)-min(l2.st.x,l2.ed.x));
    int a2=sign(max(l2.st.x,l2.ed.x)-min(l1.st.x,l1.ed.x));
    int a3=sign(max(l1.st.y,l1.ed.y)-min(l2.st.y,l2.ed.y));
    int a4=sign(max(l2.st.y,l2.ed.y)-min(l1.st.y,l1.ed.y));
    int a5 = sign(mult(l1.st,l1.ed,l2.st));
    int a6 = sign(mult(l1.st,l1.ed,l2.ed));
    int a7 = sign(mult(l2.st,l2.ed,l1.st));
    int a8 = sign(mult(l2.st,l2.ed,l1.ed));
    if(a1<0||a2<0||a3<0||a4<0)
        return 0;
    if(a5*a6<0&&a7*a8<0)
        return 1;
    return 0;
}
bool check(line l1,int n)
{
    for(int i=0; i<n; i++)
    {
        if(judge(l1,l[i]))
            return false;
    }
    return true;
}
double e[N][N];///最短路
void init()
{
    for(int i=0; i<N; i++)
    {
        for(int j=0; j<N; j++)
        {
            if(i==j)
                e[i][j]=0;
            else
                e[i][j]=inf;
        }
    }
}


int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        if(n==-1)
            break;
        memset(e,0,sizeof(e));
        //init();
        int np=1,nl=0;
        p[np].x=0.0,p[np++].y=5.0;
        for(int i=0; i<n; i++)
        {
            double x,y1,y2,y3,y4;
            cin>>x>>y1>>y2>>y3>>y4;
            p[np].x=x,p[np++].y=y1;
            p[np].x=x,p[np++].y=y2;
            p[np].x=x,p[np++].y=y3;
            p[np].x=x,p[np++].y=y4;

            l[nl].st.x=x,l[nl].st.y=0.0;
            l[nl].ed.x=x,l[nl++].ed.y=y1;

            l[nl].st.x=x,l[nl].st.y=y2;
            l[nl].ed.x=x,l[nl++].ed.y=y3;

            l[nl].st.x=x,l[nl].st.y=y4;
            l[nl].ed.x=x,l[nl++].ed.y=10.0;
        }
        p[np].x=10.0,p[np].y=5.0;
        ///枚举每个点
        for(int i=1; i<=np; i++)
        {
            for(int j=1; j<=np; j++)
            {
                line lp;
                lp.st.x=p[i].x,lp.st.y=p[i].y;
                lp.ed.x=p[j].x,lp.ed.y=p[j].y;
                if(i==j)
                    e[i][j]=0;
                else if(check(lp,nl))
                {
                    e[i][j]=e[j][i]=dis(p[i],p[j]);
                }
                else
                    e[i][j]=inf;

            }
        }
        for(int k=1; k<=np; k++)
        {
            for(int i=1; i<=np; i++)
            {
                for(int j=1; j<=np; j++)
                {
                    if(e[i][j]>e[i][k]+e[k][j])
                        e[i][j]=e[i][k]+e[k][j];
                }
            }
        }
        printf("%.2lf\n",e[1][np]);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/lee371042/article/details/86498858