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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章