POJ 2049-Finding Nemo(三维bfs解决类迷宫问题)

Finding Nemo

Time Limit: 2000MS   Memory Limit: 30000K
Total Submissions: 7902   Accepted: 1827

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 9
1 1 1 3
2 1 1 3
3 1 1 3
4 1 1 3
1 1 0 3
1 2 0 3
1 3 0 3
1 4 0 3
2 1 1
2 2 1
2 3 1
3 1 1
3 2 1
3 3 1
1 2 0
3 3 0
4 3 1
1.5 1.5
4 0
1 1 0 1
1 1 1 1
2 1 1 1
1 2 0 1
1.5 1.7
-1 -1

Sample Output

5
-1

题意:有m个墙,n个门。接下来m行 每行输入x,y,d,t分别代表左下角的(X,Y)坐标,d=1代表代表墙平行于y轴,d=0代表墙平行于x轴,t代表该行或该列上有多少墙。

思路:每个网格的坐标用网格左下角坐标来代替,用第三维来代表网格的上边和右边。然后BFS搜索,要全部搜索完取最小值。

三维map的结果0代表空地,1代表墙,2代表门,map[X][Y][0]代表此表格的上方,map[X][Y][1]代表此表格的右方。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
const int inf=0x3f3f3f3f;
struct node {
        int x, y;
        int ans;
} f1,f2;
int map[210][210][3];
int vis[210][210];
int jx[]= {0,0,1,-1};
int jy[]= {1,-1,0,0};
int min1;
void bfs(int s, int e)
{
        int i, j;
        queue<node>q;
        f1.x=s;
        f1.y=e;
        f1.ans=0;
        vis[s][e]=1;
        q.push(f1);
        min1=inf;
        while(!q.empty()) {
                f1=q.front();
                q.pop();
                if(f1.x<=0||f1.x>=199||f1.y<=0||f1.y>=199) {//边界处理,但是不能跳出,只能跳过,因为存在多个门的情况
                        min1=min(min1,f1.ans); //走出去之后,保存最小通过门数
                        continue ;
                }
                for(i=0; i<4; i++) {
                        f2.x=f1.x+jx[i];
                        f2.y=f1.y+jy[i];
                        if(i==0) {//向上走
                                if(!vis[f2.x][f2.y]&&map[f1.x][f1.y][0]!=2) {
                                        if(map[f1.x][f1.y][0]==1)
                                                f2.ans=f1.ans+1;
                                        else
                                                f2.ans=f1.ans;
                                        vis[f2.x][f2.y]=1;
                                        q.push(f2);
                                }
                        } else if(i==1) {//向下走
                                if(!vis[f2.x][f2.y]&&map[f2.x][f2.y][0]!=2) {
                                        if(map[f2.x][f2.y][0]==1)
                                                f2.ans=f1.ans+1;
                                        else
                                                f2.ans=f1.ans;
                                        vis[f2.x][f2.y]=1;
                                        q.push(f2);
                                }
                        } else if(i==2) {//向右走
                                if(!vis[f2.x][f2.y]&&map[f1.x][f1.y][1]!=2) {
                                        if(map[f1.x][f1.y][1]==1)
                                                f2.ans=f1.ans+1;
                                        else
                                                f2.ans=f1.ans;
                                        vis[f2.x][f2.y]=1;
                                        q.push(f2);
                                }
                        } else if(i==3) {//向左走
                                if(!vis[f2.x][f2.y]&&map[f2.x][f2.y][1]!=2) {
                                        if(map[f2.x][f2.y][1]==1)
                                                f2.ans=f1.ans+1;
                                        else
                                                f2.ans=f1.ans;
                                        vis[f2.x][f2.y]=1;
                                        q.push(f2);
                                }
                        }
                }
        }
}
int main()
{
        int n, m, i, j;
        int x,y,d,t;
        double a1,a2;
        int int_x,int_y;
        while(scanf("%d %d",&m,&n)!=EOF) {
                if(n==-1&&m==-1) break;
                memset(map,0,sizeof(map));
                memset(vis,0,sizeof(vis));
                for(i=0; i<m; i++) {
                        scanf("%d %d %d %d",&x, &y, &d, &t);
                        if(d) {
                                for(j=0; j<t; j++) {
                                        map[x-1][y+j][1]=2;
                                }
                        } else {
                                for(j=0; j<t; j++) {
                                        map[x+j][y-1][0]=2;
                                }
                        }
                }
                for(i=0; i<n; i++) {
                        scanf("%d %d %d",&x,&y,&d);
                        if(d) {
                                map[x-1][y][1]=1;
                        } else {
                                map[x][y-1][0]=1;
                        }
                }
                scanf("%lf %lf",&a1,&a2);
                int_x=a1;
                int_y=a2;
                if(int_x<=0||int_x>=199||int_y<=0||int_y>=199) {//后台可能出现 0,0 200+,200+,虽然不符合题目描述
                        printf("0\n");
                        continue ;
                }
                bfs(int_x,int_y);
                if(min1==inf)
                        printf("-1\n");
                else
                        printf("%d\n",min1);
        }
        return 0;
}
时间: 2024-10-09 08:35:30

POJ 2049-Finding Nemo(三维bfs解决类迷宫问题)的相关文章

POJ 2049— Finding Nemo(三维BFS)10/200

海底总动员.... 这个题开始不会建图,彻底颠覆以前我对广搜题的想法.想了好久, 忽然想到省赛时HYPO让我做三维BFS来着,一直没做,看到POJ计划这个题,就是三维BFS解题,就做了一下, 对于这个题....实在不知道说什么好,又坑.又SB,POJ的后台数据和题目描述的完全不一样,看了DIscuss之后开始 改动代码,最后改的又臭又长,搜了无数题解找数据,卡了整整两天. 挥挥洒洒 160行....同时也是我第一次使用  三维建图+BFS,纪念一下! 2049 算是我攻克POJ计划的第一个卡两天

POJ 2049 Finding Nemo BFS

题目大意:给你一个奇奇怪怪的迷宫, 这个迷宫包括墙和门.再给你一个起始坐标, 问你从迷宫内到外面至少要穿越多少的门. 题目分析: 穿越多少门等同于路过了多少个格子. 为此我们可以将整个地图中的格子,门,墙,墙的交界处(格子的顶点)全部抽象成点. 即坐标(奇数,奇数)为格子的坐标,坐标(奇数,偶数)或坐标(偶数,奇数)为门或墙的坐标,坐标(偶数,偶数)为格子的顶点. 这样题目就转化成了从起始点所在的格子走到迷宫外的格子最少要经过多少个格子,用step[i][j]表示走出迷宫后遇到的第一个格子的坐标

POJ 2049 Finding Nemo 优先队列 STL

题目链接:http://poj.org/problem?id=2049 题目利用了<海底总动员>的情节,小丑鱼尼莫迷路了,他老爸去营救他便是题意. 题目给出了这样的地图,说是假设地图由墙和门组成,忽略墙的厚度,地图上有门,没有墙的地方是可以自由行动的问可以经过最少多少道门便可以营救到尼莫. 这个题给的数据是墙的交点为整数点,但鱼爸爸实在非墙的地方自由移动. 因此,这个题有两个难点: 1.如果建图保存地图 2.如何在地图上遍历 由于题目是给出一个点(x,y),来表示一段墙 我便用一对X,Y来表示

POJ 2049 Finding Nemo

Finding Nemo Time Limit: 2000MS   Memory Limit: 30000K Total Submissions: 8631   Accepted: 2019 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. Therefo

POJ 2251 Dungeon Master --- 三维BFS(用BFS求最短路)

POJ 2251 题目大意: 给出一三维空间的地牢,要求求出由字符'S'到字符'E'的最短路径,移动方向可以是上,下,左,右,前,后,六个方向,每移动一次就耗费一分钟,要求输出最快的走出时间.不同L层的地图,相同RC坐标处是相连通的.(.可走,#为墙) 解题思路:从起点开始分别往6个方向进行BFS(即入队),并记录步数,直至队为空.若一直找不到,则困住. /* POJ 2251 Dungeon Master --- 三维BFS(用BFS求最短路) */ #include <cstdio> #i

POJ 2251:Dungeon Master(三维BFS)

Dungeon Master Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 16178 Accepted: 6268 Description You are trapped in a 3D dungeon and need to find the quickest way out! The dungeon is composed of unit cubes which may or may not be filled wit

poj 2251 Dungeon Master(三维BFS)(中等)

Dungeon Master Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 20598   Accepted: 7971 Description You are trapped in a 3D dungeon and need to find the quickest way out! The dungeon is composed of unit cubes which may or may not be filled

【POJ 2049】Finding Nemo

[POJ 2049]Finding Nemo 迷宫类Bfs,不同于之前的是之前是点 这次是房间,我的做法是把每个房间看做一个点(移动地图使房间为整型坐标 便于用数组下表表示房间坐标) 上下左右是墙/门/无用1 0 -1表示 然后Bfs遍历即可 坑点有x/y<0 和x/y > 199的情况 贡献了好多个RE 上代码 #include <cstdio> #include <cstring> #include <queue> using namespace std

POJ - 2251 Dungeon Master(三维BFS)

题目链接:http://poj.org/problem?id=2251 题意:三维BFS. 题解:大水题,只不过多加了两个方向 1 //poj2251 2 #include <queue> 3 #include <cstring> 4 #include <iostream> 5 #include <algorithm> 6 using namespace std; 7 int sx,sy,sz,ex,ey,ez,L,R,C; 8 const int INF=