逃离迷宫
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 19656 Accepted Submission(s):
4783
Problem Description
给定一个m × n (m行,
n列)的迷宫,迷宫中有两个位置,gloria想从迷宫的一个位置走到另外一个位置,当然迷宫中有些地方是空地,gloria可以穿越,有些地方是障碍,她必须绕行,从迷宫的一个位置,只能走到与它相邻的4个位置中,当然在行走过程中,gloria不能走到迷宫外面去。令人头痛的是,gloria是个没什么方向感的人,因此,她在行走过程中,不能转太多弯了,否则她会晕倒的。我们假定给定的两个位置都是空地,初始时,gloria所面向的方向未定,她可以选择4个方向的任何一个出发,而不算成一次转弯。gloria能从一个位置走到另外一个位置吗?
Input
第1行为一个整数t (1 ≤ t ≤
100),表示测试数据的个数,接下来为t组测试数据,每组测试数据中,
第1行为两个整数m, n (1 ≤ m, n ≤ 100),分别表示迷宫的行数和列数,接下来m行,每行包括n个字符,其中字符'.'表示该位置为空地,字符'*'表示该位置为障碍,输入数据中只有这两种字符,每组测试数据的最后一行为5个整数k, x1, y1, x2, y2 (1 ≤ k ≤ 10, 1 ≤ x1, x2 ≤ n, 1 ≤ y1, y2 ≤ m),其中k表示gloria最多能转的弯数,(x1, y1), (x2, y2)表示两个位置,其中x1,x2对应列,y1, y2对应行。
第1行为两个整数m, n (1 ≤ m, n ≤ 100),分别表示迷宫的行数和列数,接下来m行,每行包括n个字符,其中字符'.'表示该位置为空地,字符'*'表示该位置为障碍,输入数据中只有这两种字符,每组测试数据的最后一行为5个整数k, x1, y1, x2, y2 (1 ≤ k ≤ 10, 1 ≤ x1, x2 ≤ n, 1 ≤ y1, y2 ≤ m),其中k表示gloria最多能转的弯数,(x1, y1), (x2, y2)表示两个位置,其中x1,x2对应列,y1, y2对应行。
Output
每组测试数据对应为一行,若gloria能从一个位置走到另外一个位置,输出“yes”,否则输出“no”。
Sample Input
2
5 5
...**
*.**.
.....
.....
*....
1 1 1 1 3
5 5
...**
*.**.
.....
.....
*....
2 1 1 1 3
Sample Output
no
yes
我们举个例子: 要判断从S能否到T。
我们用used[][]来记录从S出发第一次到达某个位置时的转弯次数(也可以说成是起点S到该位置至少转弯次数),若为-1说明该点还未遍历。
初始化used 为 -1
上图:
我们假设遍历方向为左,上,右,下。为了简化问题,我们假设没有障碍物。
第一步:遍历完四个方向,对于若used[ x ][ y ]为负1的点,used[ x ][ y ] = 遍历起点次数 + 1 并且入队列(红线上的点除了遍历起点外全部入队 )。
二:继续上次同样的做法
重复上面的做法,因为蓝线上的点除了遍历起点之外used值全为-1,我们把它们全部入队且 used值 = 遍历起点的used + 1 = 1,证明从S点出发到这条线上任意一点都会至少转一次弯。
三:同上面
遍历完左边首先入队的点后,我们要遍历上方入队的点。图中给出已遍历位置的used值。我们开始遍历上方入队的点,如黄线,它也要遍历四个方向,但是对于已经计算过used值的点,就不能再更新也不能让它们入队,只将那些used值为-1的点更新used值后入队。
四:由S上方的第二个点开始遍历,我们看到会到达T点,这时计算T位置的used值 = 0 + 1 = 1。得到答案。
上面只是用图简单模拟下BFS过程中怎么记录转弯次数,当然这是最简单的情况。
思路:对队列里面的坐标(x,y)做选择时,每次选择一个方向(共四个方向)走到不能走为止,将沿途经过的所有used值 = -1的点入队并更新used值(对used不为-1的点不作处理)。队列为空还无法到终点,输出no。若能遍历到终点,判断used值是否大于要求的k,若大于输出no,否则输出yes。
#include<stdio.h> #include<string.h> #include<queue> #define MAX 110 using namespace std; char map[MAX][MAX]; int vis[MAX][MAX]; int n,m; int w,x1,x2,y1,y2; void getmap() { int i,j; for(i=1;i<=n;i++) { getchar(); for(j=1;j<=m;j++) { scanf("%c",&map[i][j]); } } } struct node { int x,y; }; int judge(int x,int y) { if(x>0&&x<=n&&y>0&&y<=m&&map[x][y]!='*') return 1; return 0; } void bfs() { int move[4][2]={0,1,0,-1,1,0,-1,0}; int i,j,ok=0; queue<node>q; node beg,end; beg.x=x1; beg.y=y1; q.push(beg); while(!q.empty()) { end=q.front(); q.pop(); if(end.x==x2&&end.y==y2) { if(vis[end.x][end.y]<=w) { printf("yes "); ok=1; } else break; } else { for(i=0;i<4;i++) { beg.x=end.x+move[i][0]; beg.y=end.y+move[i][1]; while(judge(beg.x,beg.y)) { if(vis[beg.x][beg.y]==-1) { vis[beg.x][beg.y]=vis[end.x][end.y]+1; q.push(beg); } beg.x+=move[i][0];//沿着这个方向继续走 beg.y+=move[i][1]; } } } } if(!ok) printf("no "); } int main() { int t; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); getmap(); scanf("%d%d%d%d%d",&w,&y1,&x1,&y2,&x2); memset(vis,-1,sizeof(vis)); bfs(); } return 0; }