POJ1556-The Doors

The Doors
Time Limit: 1000MS Memory Limit: 10000K
Total Submissions: 6161 Accepted: 2475

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.

2
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
//别人读硕水题,但是此题俺真心没想到,花了一天时间,唉,说多了都是泪
/*
3
4 4 7 8 9
5 5.5 7 8 9
7 6 8 9 9.
#include<iostream>//我的代码,最后还是WA了,原因是我没考虑墙和墙之间有些可以直达而不是一个一个去判断,坑啊!!!
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#define eps 1e-8
const double INF=9999999.0;
const int Max=101;
double Map[Max][Max];
int Mark[Max];
double dis[Max];
using namespace std;
typedef struct WAll
{
    double dx;
    double d1_y;
    double d2_y;
    double d3_y;
    double d4_y;
}wall;
wall w[Max];
typedef struct Node
{
    double x;
    double y;
    int num;
}point;
typedef struct Save
{
    point u;
    point v;
    point o;
    int sum;
    int kind;
}save;
save sa[Max];
int sign(double x)
{
    return (x>eps)-(x<-eps);
}
double multi(point p0,point p1,point p2)
{
	return(p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
}
//相交返回true,否则为false,接口为两线段的端点
bool isIntersected(point s1,point e1,point s2,point e2)
{
	return(max(s1.x,e1.x)>=min(s2.x,e2.x))&& (max(s2.x,e2.x)>=min(s1.x,e1.x))&&(max(s1.y,e1.y)>=min(s2.y,e2.y))&&(max(s2.y,e2.y)>=min(s1.y,e1.y))&&(multi(s1,s2,e1)*multi(s1,e1,e2)>0)&&(multi(s2,s1,e2)*multi(s2,e2,e1)>0);
}
double DDistance(point p1,point p2)// 返回两点之间欧氏距离
{
    //cout<<(p1.x-p2.x)<<" "<<(p1.y-p2.y)<<endl;
    return( sqrt( (p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y) ) );
}
double slope(point u,point v)
{
    return (v.y-u.y)/(v.x-u.x);
}
int main()
{
    int n,m,i,j,k,ex;
    point u1,u2,u3,u4,up,down,s,e;
    void dijkstra(int x,int y,int ex);
    while(cin>>n&&(n!=-1))
    {
        //memset(Map,INF,sizeof(Map));
        //memset(Mark,0,sizeof(Mark));
        //memset(dis,INF,sizeof(dis));
        for(i=0;i<Max;i++)
        {
            for(j=0;j<Max;j++)
            {
                Map[i][j]=INF;
            }
            Mark[i]=0;
            dis[i]=INF;
        }

        s.x=0.0;
        s.y=5.0;
        e.x=10.0;
        e.y=5.0;
        ex=1;
        k=1;
        for(i=1;i<=n;i++)
        {
            cin>>w[i].dx>>w[i].d1_y>>w[i].d2_y>>w[i].d3_y>>w[i].d4_y;
            down.x=w[i].dx;
            down.y=0.0;
            u1.x=w[i].dx;
            u1.y=w[i].d1_y;
            u2.x=w[i].dx;
            u2.y=w[i].d2_y;
            u3.x=w[i].dx;
            u3.y=w[i].d3_y;
            u4.x=w[i].dx;
            u4.y=w[i].d4_y;
            up.x=w[i].dx;
            up.y=10.0;
            if(isIntersected(s,e,down,u1))
            {
                //cout<<"YES1"<<endl;
                sa[ex].sum=k;
                sa[ex].u=down;
                sa[ex].v=u1;
                sa[ex].v.num=k++;
                sa[ex].kind=-1;
                ex+=1;

            }
            else if(isIntersected(s,e,u2,u3))
            {
                //cout<<"YES2"<<endl;
                sa[ex].sum=k;
                sa[ex].u=u2;
                sa[ex].u.num=k++;
                sa[ex].v=u3;
                sa[ex].v.num=k++;
                sa[ex].kind=0;
                ex+=1;
            }else if(isIntersected(s,e,u4,up))
            {
                //cout<<"YES3"<<endl;
                sa[ex].sum=k;
                sa[ex].u=u4;
                sa[ex].u.num=k++;
                sa[ex].v=up;
                sa[ex].kind=1;
                ex+=1;
            }
        }
        sa[0].o.x=s.x;
        sa[0].o.y=s.y;
        sa[0].sum=0;
        sa[0].kind=2;
        sa[ex].o.x=e.x;
        sa[ex].o.y=e.y;
        sa[ex].sum=k;
        sa[ex].kind=2;
        for(i=1;i<=ex;i++)
        {
                if(sa[i-1].kind==-1)
                {
                    //cout<<-1;
                    int nn=sa[i-1].sum;
                    if(sa[i].kind==-1)
                    {
                        //cout<<" -1"<<endl;
                        int mm=sa[i].sum;
                        Map[nn][mm]=Map[mm][nn]=DDistance(sa[i-1].v,sa[i].v);
                        //cout<<nn<<" "<<mm<<" "<<DDistance(sa[i-1].v,sa[i].v)<<endl;
                    }
                    if(sa[i].kind==0)
                    {
                        //cout<<" 0"<<endl;
                        int mm=sa[i].sum;
                        Map[nn][mm]=Map[mm][nn]=DDistance(sa[i-1].v,sa[i].u);
                        //cout<<nn<<" "<<mm<<" "<<DDistance(sa[i-1].v,sa[i].u)<<endl;
                        mm+=1;
                        Map[nn][mm]=Map[mm][nn]=DDistance(sa[i-1].v,sa[i].v);
                        //cout<<nn<<" "<<mm<<" "<<DDistance(sa[i-1].v,sa[i].v)<<endl;
                    }
                    if(sa[i].kind==1)
                    {
                        //cout<<" 1"<<endl;
                        int mm=sa[i].sum;
                        Map[nn][mm]=Map[mm][nn]=DDistance(sa[i-1].v,sa[i].u);
                        //cout<<nn<<" "<<mm<<" "<<DDistance(sa[i-1].v,sa[i].u)<<endl;
                    }
                    if(sa[i].kind==2)
                    {
                        //cout<<" 2"<<endl;
                        int mm=sa[i].sum;
                        Map[nn][mm]=Map[mm][nn]=DDistance(sa[i-1].v,sa[i].o);
                        //cout<<nn<<" "<<mm<<" "<<DDistance(sa[i-1].v,sa[i].o)<<endl;
                    }
                }
                else if(sa[i-1].kind==0)
                {
                    //cout<<0;
                    int nn=sa[i-1].sum;
                    int nnn=nn+1;
                    if(sa[i].kind==-1)
                    {
                        //cout<<" -1"<<endl;
                        int mm=sa[i].sum;
                        Map[nn][mm]=Map[mm][nn]=DDistance(sa[i-1].u,sa[i].v);
                        //cout<<nn<<" "<<mm<<" "<<DDistance(sa[i-1].u,sa[i].v)<<endl;
                        Map[nnn][mm]=Map[mm][nnn]=DDistance(sa[i-1].v,sa[i].v);
                        //cout<<nn<<" "<<mm<<" "<<DDistance(sa[i-1].v,sa[i].v)<<endl;
                    }
                    if(sa[i].kind==0)
                    {
                        //cout<<" 0"<<endl;
                        int mm=sa[i].sum;
                        int mmm=mm+1;
                        Map[nn][mm]=Map[mm][nn]=DDistance(sa[i-1].u,sa[i].u);
                        //cout<<nn<<" "<<mm<<" "<<DDistance(sa[i-1].u,sa[i].u)<<endl;
                        Map[nn][mmm]=Map[mmm][nn]=DDistance(sa[i-1].u,sa[i].v);
                        //cout<<nn<<" "<<mmm<<" "<<DDistance(sa[i-1].u,sa[i].v)<<endl;
                        Map[nnn][mm]=Map[mm][nnn]=DDistance(sa[i-1].v,sa[i].u);
                       // cout<<nnn<<" "<<mm<<" "<<DDistance(sa[i-1].v,sa[i].u)<<endl;
                        Map[nnn][mmm]=Map[mmm][nnn]=DDistance(sa[i-1].v,sa[i].v);
                        //cout<<nnn<<" "<<mmm<<" "<<DDistance(sa[i-1].v,sa[i].v)<<endl;
                    }
                    if(sa[i].kind==1)
                    {
                        //cout<<" 1"<<endl;
                        int mm=sa[i].sum;
                        Map[nn][mm]=Map[mm][nn]=DDistance(sa[i-1].u,sa[i].u);
                        //cout<<nn<<" "<<mm<<" "<<DDistance(sa[i-1].u,sa[i].u)<<endl;
                        Map[nnn][mm]=Map[mm][nnn]=DDistance(sa[i-1].v,sa[i].u);
                        //cout<<nn<<" "<<mm<<" "<<DDistance(sa[i-1].v,sa[i].u)<<endl;
                    }
                    if(sa[i].kind==2)
                    {
                        //cout<<" 2"<<endl;
                        int mm=sa[i].sum;
                        Map[nn][mm]=Map[mm][nn]=DDistance(sa[i-1].u,sa[i].o);
                        //cout<<nn<<" "<<mm<<" "<<DDistance(sa[i-1].u,sa[i].o)<<endl;
                        Map[nnn][mm]=Map[mm][nnn]=DDistance(sa[i-1].v,sa[i].o);
                        //cout<<nnn<<" "<<mm<<" "<<DDistance(sa[i-1].v,sa[i].o)<<endl;
                    }
                }
                else if(sa[i-1].kind==1)
                {
                    //cout<<1;
                    int nn=sa[i-1].sum;
                    if(sa[i].kind==-1)
                    {
                        //cout<<" -1"<<endl;
                        int mm=sa[i].sum;
                        Map[nn][mm]=Map[mm][nn]=DDistance(sa[i-1].u,sa[i].v);
                        //cout<<nn<<" "<<mm<<" "<<DDistance(sa[i-1].u,sa[i].v)<<endl;
                    }
                    if(sa[i].kind==0)
                    {
                        //cout<<" 0"<<endl;
                        int mm=sa[i].sum;
                        Map[nn][mm]=Map[mm][nn]=DDistance(sa[i-1].u,sa[i].u);
                        //cout<<nn<<" "<<mm<<" "<<DDistance(sa[i-1].u,sa[i].u)<<endl;
                        mm+=1;
                        Map[nn][mm]=Map[mm][nn]=DDistance(sa[i-1].u,sa[i].v);
                        //cout<<nn<<" "<<mm<<" "<<DDistance(sa[i-1].u,sa[i].v)<<endl;
                    }
                    if(sa[i].kind==1)
                    {
                        //cout<<" 1"<<endl;
                        int mm=sa[i].sum;
                        Map[nn][mm]=Map[mm][nn]=DDistance(sa[i-1].u,sa[i].u);
                        //cout<<nn<<" "<<mm<<" "<<DDistance(sa[i-1].u,sa[i].u)<<endl;
                    }
                    if(sa[i].kind==2)
                    {
                        //cout<<" 2"<<endl;
                        int mm=sa[i].sum;
                        Map[nn][mm]=Map[mm][nn]=DDistance(sa[i-1].u,sa[i].o);
                        //cout<<nn<<" "<<mm<<" "<<DDistance(sa[i-1].u,sa[i].o)<<endl;
                    }
                }
                else if(sa[i-1].kind==2)
                {
                    //cout<<2;
                    int nn=sa[i-1].sum;
                    if(sa[i].kind==-1)
                    {
                        //cout<<" -1"<<endl;
                        int mm=sa[i].sum;
                        Map[nn][mm]=Map[mm][nn]=DDistance(sa[i-1].o,sa[i].v);
                        //cout<<nn<<" "<<mm<<" "<<DDistance(sa[i-1].o,sa[i].v)<<endl;
                    }
                    if(sa[i].kind==0)
                    {
                        //cout<<" 0"<<endl;
                        int mm=sa[i].sum;
                        Map[nn][mm]=Map[mm][nn]=DDistance(sa[i-1].o,sa[i].u);
                        //cout<<nn<<" "<<mm<<" "<<DDistance(sa[i-1].o,sa[i].u)<<endl;
                        mm+=1;
                        Map[nn][mm]=Map[mm][nn]=DDistance(sa[i-1].o,sa[i].v);
                        //cout<<nn<<" "<<mm<<" "<<DDistance(sa[i-1].o,sa[i].v)<<endl;
                    }
                    if(sa[i].kind==1)
                    {
                        //cout<<" 1"<<endl;
                        int mm=sa[i].sum;
                        Map[nn][mm]=Map[mm][nn]=DDistance(sa[i-1].o,sa[i].u);
                        //cout<<nn<<" "<<mm<<DDistance(sa[i-1].o,sa[i].u)<<endl;
                    }
                    if(sa[i].kind==2)
                    {
                        //cout<<" 2"<<endl;
                        int mm=sa[i].sum;
                        Map[nn][mm]=Map[mm][nn]=DDistance(sa[i-1].o,sa[i].o);
                        //cout<<nn<<" "<<mm<<" "<<DDistance(sa[i-1].o,sa[i].o)<<endl;
                    }
                }
            }
        dijkstra(0,k,k+1);
    }
    return 0;
}
void dijkstra(int start,int end,int n)
{
    int i,j,k;
    double Min;
    for(i=0;i<n;i++)
    dis[i]=Map[start][i];
    dis[start]=0;
    Mark[start]=1;
    for(j=0;j<n;j++)
    {
      Min=INF;
      k=start;
      for(i=0;i<n;i++)
      {
         if(!Mark[i]&&Min>dis[i])
         {
             Min=dis[i];
             k=i;
         }
      }
      Mark[k]=1;
      //cout<<Min<<endl;
      if(Min==INF)
      break;
      for(i=0;i<n;i++)
      {
        if(!Mark[i]&&(Min+Map[k][i])<dis[i])
          dis[i]=Min+Map[k][i];
      }
    }
    printf("%.2lf\n",dis[end]);
}
*/
#include <iostream>//别人的AC代码,顿时感觉自己弱爆了
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;

double g[100][100], dist[100];
bool visit[100];
int n, t_id; //n为墙数,t_id为终点在图中的编号

const double eps = 1e-8;
const double inf = 999999999;

/*door[i][j][k]表示第i堵墙的j扇门的第k端点
  s为起点,t为终点
*/
struct Point {
    double x, y;
} door[20][2][2], s, t;

//叉积
double multi(Point p1, Point p2, Point p0) {
    return (p1.x - p0.x) * (p2.y - p0.y) - (p1.y - p0.y) * (p2.x - p0.x);
}

//判断线段ab与直线cd是否相交,过端点也算相交
bool cross(Point a, Point b, Point c, Point d) {
    if (multi(a, d, c) * multi(b, d, c) > eps) return false;
    return true;
}

//求两点距离
double dis(Point a, Point b) {
    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}

//判断两点是否能够直接相连不撞墙
bool judge(int i, int j, Point a, Point b) {
     for (; i <= j; i++)
         if (cross(door[i][0][0], door[i][0][1], a, b) == false && cross(door[i][1][0], door[i][1][1], a, b) == false)
            return false;
     return true;
}

//构图:将不同墙上的门之间的距离构造进图
void make_map() {
     int i, j, k, l, p, q, x, y;

     for (i = 0; i < n-1; i++)
         for (j = 0; j < 2; j++)
            for (k = 0; k < 2; k++) {
                x = 4*i+2*j+k+1;
                for (l = i + 1; l < n; l++)
                    for (p = 0; p < 2; p++)
                        for (q = 0; q < 2; q++) {
                            y = 4*l+2*p+q+1;
                            if (judge(i+1, l-1, door[i][j][k], door[l][p][q]))
                                g[x][y] = dis(door[i][j][k], door[l][p][q]);
                        }
            }
}

//求最短距
double Dikstra() {
    int i, j, cur;
    double tmp;

    memset(visit, false, sizeof (visit));
    for (i = 1; i <= t_id; i++) dist[i] = inf;
    dist[0] = 0;
    for (i = 0; i <= t_id; i++) {
        tmp = inf;
        cur = -1;
        for (j = 0; j <= t_id; j++)
            if (!visit[j] && dist[j] < tmp) {
                tmp = dist[j];
                cur = j;
            }
        visit[cur] = true;
        if (cur == t_id) break;
        for (j = 0; j <= t_id; j++) {
            if (!visit[j] && g[cur][j] > eps && dist[cur] + g[cur][j] + eps < dist[j])
                dist[j] = dist[cur] + g[cur][j];
        }
    }
    return dist[t_id];
}

int main()
{
    double x, y1, y2, y3, y4;
    int i, j, k;

    //初始化起点终点坐标
    s.x = 0; s.y = 5;
    t.x = 10; t.y = 5;
    while (scanf ("%d", &n) && n != -1) {
        for (i = 0; i < n; i++) {
            scanf ("%lf%lf%lf%lf%lf", &x, &y1, &y2, &y3, &y4);
            door[i][0][0].x = door[i][0][1].x = door[i][1][0].x = door[i][1][1].x = x;
            door[i][0][0].y = y1; door[i][0][1].y = y2;
            door[i][1][0].y = y3; door[i][1][1].y = y4;
        }
        memset(g, 0, sizeof (g));
        t_id = 4 * n + 1; //求出终点在图中的编号
        if (judge(0, n-1, s, t)) { //r若起点终点可以直接相连,则这两点距离即为答案
            printf ("%.2lf\n", dis(s, t));
            continue;
        }
        int id;
        //将起点和终点与中间的墙上的门的距离构造进图
        for (i = 0; i < n; i++) {
            for (j = 0; j < 2; j++) {
                for (k = 0; k < 2; k++) {
                    id = 4*i+2*j+k+1; //求出门上的点在图中的编号
                    if (judge(0, i-1, s, door[i][j][k])) g[0][id] = dis(s, door[i][j][k]);
                    if (judge(i+1, n-1, door[i][j][k], t)) g[id][t_id] = dis(door[i][j][k], t);
                }
            }
        }
        make_map();
        printf ("%.2lf\n", Dikstra());
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值