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;
}
posted @ 2021-04-22 11:13  IdiotNe  阅读(33)  评论(0编辑  收藏  举报