POJ 3083
一道非常有意思的题
小时候看书看到过这种迷宫走法
整道题可以分为两个部分讨论:
- BFS部分,很简单,而且由于图的设置,使得这道题没什么难度
- 模拟这种迷宫走法的部分,开始很不好想关于这种转向的走法,后面取巧这么设置(以左墙寻路为例): 首先,决定下一步的step变量,按着索引递增,四个方向设置成逆时针(顺也可,就是一个符号处理的问题,只要满足一直即可),寻路过程中记录一个to(toward)记录当前寻路朝向,每当在一个新的地方寻路的时候,首先将这个方向逆时针掰过来,再顺时针遍历四个可以找的方向,中间如果找到路,就跳出来
中间DEBUG时候遇到过死循环,是关于模运算中负数的处理,所以干脆将这个模运算利用位运算解决
#include <iostream>
#include <algorithm>
#include <queue>
#include <string>
#include <vector>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <string>
#include <stack>
#include <map>
#include <set>
using namespace std;
const int maxw= 45;
const int LEFT= -1;
const int RIGHT= 1;
struct Node
{
int i, j;
Node(int _i= 0, int _j= 0) : i(_i), j(_j) {}
};
int w, h;
char mz[maxw][maxw];
bool vis[maxw][maxw];
int dis[maxw][maxw];
int step[4][2]= {{1, 0}, {0, -1}, {-1, 0}, {0, 1}};
int BFS(int si, int sj)
{
queue<Node> Q;
memset(vis, 0, sizeof(vis));
vis[si][sj]= 1;
dis[si][sj]= 1;
Q.push(Node(si, sj));
Node cur;
int i, j, v;
while (!Q.empty()){
cur= Q.front();
Q.pop();
i= cur.i;
j= cur.j;
v= dis[i][j]+1;
for (int p= 0; p< 4; ++p){
int ni= i+step[p][0], nj= j+step[p][1];
if ('E'== mz[ni][nj]){
return v;
}
if ('.'== mz[ni][nj] && !vis[ni][nj]){
vis[ni][nj]= 1;
dis[ni][nj]= v;
Q.push(Node(ni, nj));
}
}
}
return -1;
}
int Search(const int si, const int sj, const int dir)
{
int ni, nj;
int to= -1;
for (int i= 0; i< 4; ++i){
ni= si+step[i][0];
nj= sj+step[i][1];
if ('.'== mz[ni][nj]){
to= i;
break;
}
}
dis[si][sj]= 1;
dis[ni][nj]= 2;
int v;
while ('E'!= mz[ni][nj]){
v= dis[ni][nj]+1;
to= (to+dir*1)&3;
for (int i= 0; i< 4; ++i){
int x= ni+step[to][0], y= nj+step[to][1];
if ('E'== mz[x][y]){
return v;
}
if ('.'== mz[x][y]){
dis[x][y]= v;
ni= x;
nj= y;
break;
}
to= (to-dir*1)&3;
}
}
return -1;
}
int main()
{
int kase;
scanf("%d", &kase);
while (kase--){
scanf("%d %d", &w, &h);
memset(mz, '#', sizeof(mz));
int si, sj;
for (int i= 1; i<= h; ++i){
scanf(" %s", mz[i]+1);
for (int j= 1; j<= w; ++j){
if ('S'== mz[i][j]){
si= i;
sj= j;
break;
}
}
}
int ans_l, ans_r, ans_s;
ans_l= Search(si, sj, LEFT);
ans_r= Search(si, sj, RIGHT);
ans_s= BFS(si, sj);
printf("%d %d %d\n", ans_l, ans_r, ans_s);
}
return 0;
}