POJ 2049 Finding Nemo ( BFS)

来源:互联网 发布:电脑软件无法安装 编辑:程序博客网 时间:2024/05/18 22:42
Finding Nemo
Time Limit: 2000MS Memory Limit: 30000KTotal Submissions: 8273 Accepted: 1924

Description

Nemo is a naughty boy. One day he went into the deep sea all by himself. Unfortunately, he became lost and couldn't find his way home. Therefore, he sent a signal to his father, Marlin, to ask for help. 
After checking the map, Marlin found that the sea is like a labyrinth with walls and doors. All the walls are parallel to the X-axis or to the Y-axis. The thickness of the walls are assumed to be zero. 
All the doors are opened on the walls and have a length of 1. Marlin cannot go through a wall unless there is a door on the wall. Because going through a door is dangerous (there may be some virulent medusas near the doors), Marlin wants to go through as few doors as he could to find Nemo. 
Figure-1 shows an example of the labyrinth and the path Marlin went through to find Nemo. 

We assume Marlin's initial position is at (0, 0). Given the position of Nemo and the configuration of walls and doors, please write a program to calculate the minimum number of doors Marlin has to go through in order to reach Nemo.

Input

The input consists of several test cases. Each test case is started by two non-negative integers M and N. M represents the number of walls in the labyrinth and N represents the number of doors. 
Then follow M lines, each containing four integers that describe a wall in the following format: 
x y d t 
(x, y) indicates the lower-left point of the wall, d is the direction of the wall -- 0 means it's parallel to the X-axis and 1 means that it's parallel to the Y-axis, and t gives the length of the wall. 
The coordinates of two ends of any wall will be in the range of [1,199]. 
Then there are N lines that give the description of the doors: 
x y d 
x, y, d have the same meaning as the walls. As the doors have fixed length of 1, t is omitted. 
The last line of each case contains two positive float numbers: 
f1 f2 
(f1, f2) gives the position of Nemo. And it will not lie within any wall or door. 
A test case of M = -1 and N = -1 indicates the end of input, and should not be processed.

Output

For each test case, in a separate line, please output the minimum number of doors Marlin has to go through in order to rescue his son. If he can't reach Nemo, output -1.

Sample Input

8 91 1 1 32 1 1 33 1 1 34 1 1 31 1 0 31 2 0 31 3 0 31 4 0 32 1 12 2 12 3 13 1 13 2 13 3 11 2 03 3 04 3 11.5 1.54 01 1 0 11 1 1 12 1 1 11 2 0 11.5 1.7-1 -1

Sample Output

5

-1

n面墙 描述为 x,y,d,t (x,y为墙的起点,d是墙的方向,0平行于x轴,1平行于y轴,t是墙的长度)

m道门 描述为 x,y,d (与墙基本相同,只不过t默认为1)

两个实数 代表Marlin的坐标 ,问他穿过多少道门走出迷宫 (若坐标在迷宫外,结果为0),不能走出输出-1

迷宫每个元素是一个格子,可以选格子的左下角来建图,每个点需要记录它四个边的状态和走到该点的步数

用1来代表墙,0代表门,-1代表既没墙也没门的地方

对于一个格子的左下角,如果它的墙与X轴平行,则它的下边标记为1,这时对于这个格子下面的格子,上边也是个墙,所以也应标记为1

如果与Y轴平行,则该格子的左边为墙,标记为1,对于该格子左面的格子,它的右边也是墙,应标记为1(整个图的左下角为(1,1,),注意处理边界)

最后需要注意的是最后给出的坐标可能在[1,199]之外,直接输出0,因为这个原因一直RE。。。。

#include <iostream>#include <cstdio>#include <cstring>#include <stdlib.h>#include <algorithm>#include <queue>#define N 201#define inf 0x3f3f3f3fusing namespace std;struct node{    int step;   //记录穿过的门数    int f[4];   //0,1,2,3 表示上下左右四个边} a[N][N];bool v[N][N];int xx[]= {0,0,-1,1};  //上下左右int yy[]= {1,-1,0,0};void bfs(int x,int y){    queue<pair<int,int> >q;    q.push(pair<int ,int >(x,y));    a[x][y].step=0;    v[x][y]=true;    while(!q.empty())    {        x=q.front().first;        y=q.front().second;        q.pop();        for(int i=0; i<4; i++)        {            int s=x+xx[i];            int e=y+yy[i];            if(s<1 || e<1 ||s>199 || e>199) continue;            if(a[x][y].f[i]==-1)            {                printf("%d\n",a[x][y].step);                return ;            }            if(!v[s][e] && a[x][y].f[i]==0)            {                v[s][e]=true;                a[s][e].step=a[x][y].step+1;                q.push(pair<int, int>(s,e));            }        }    }    printf("-1\n");}int main(){    int n,m;    while(~scanf("%d%d",&n,&m))    {        if(n==-1 && m==-1) break;        for(int i=0; i<N; i++)        {            for(int j=0; j<N; j++)            {                a[i][j].f[0]=-1;                a[i][j].f[1]=-1;                a[i][j].f[2]=-1;                a[i][j].f[3]=-1;                a[i][j].step=0;            }        }        while(n--)        {            int x,y,d,t;            scanf("%d%d%d%d",&x,&y,&d,&t);    //格子左下角的坐标标记整个格子            if(d)             // 墙与y轴平行            {                for(int i=0; i<t; i++)                {                    a[x][y+i].f[2]=1;      //点(x,y)向上t格的左边标记为墙                    if(x>1)                //当横坐标为1的时候,左面没有格子                        a[x-1][y+i].f[3]=1;   //点(x,y)左面的格子(x-1,y)的右面标记为墙                }            }            else              //墙与x轴平行            {                for(int i=0; i<t; i++)                {                    a[x+i][y].f[1]=1;      //点(x,y)向右t格的下边标记为墙                    if(y>1)                //当纵坐标为1的时候,下面没有格子                        a[x+i][y-1].f[0]=1;  //点(x,y)下面的格子(x,y-1)的上面标记为墙                }            }        }        while(m--)           //同墙        {            int x,y,d;            scanf("%d%d%d",&x,&y,&d);            if(d)            {                a[x][y].f[2]=0;                if(x>1)                    a[x-1][y].f[3]=0;            }            else            {                a[x][y].f[1]=0;                if(y>1)                    a[x][y-1].f[0]=0;            }        }        double s,e;        memset(v,false,sizeof(v));        cin>>s>>e;        if( s<1 || s>199 || e<1 || e>199)    //没有这个会RE        {            printf("0\n");            continue;        }        bfs((int)s,int(e));    }    return 0;}



0 0