1. 程式人生 > >POJ 3083 Children of the Candy Corn(BFS + DFS)

POJ 3083 Children of the Candy Corn(BFS + DFS)

題意:給定w×h的矩陣,分別求從S到T:沿著左邊牆壁的走的路徑,沿著右邊牆壁走的路徑,最短路徑。

思路:最短路徑直接利用bfs搜尋可得。對於沿著牆壁走,記錄當前的狀態為(當前點所在的座標,當前前行的方向),例如沿著左邊牆壁走,若一下不會做,可以分情況考慮,以當前所在點為中心的3×3的矩陣中,分別討論剩下8個格子的是點還是牆時的走法。最後可以發現規律,沿著左邊牆壁走,按照左上右下,即順時針的方向判斷,若先判斷的方向可以走,就直接走。同理,沿著右邊牆壁走,按照右上左下,即逆時針的方向判斷。

程式碼:

#include <stdio.h>
#include <string.h>
#include <iostream> #include <algorithm> #include <math.h> #include <queue> using namespace std; const int INF = 0x3f3f3f3f; struct Node { int x, y; int path; // dfs時記錄為當前的方向 }; char _map[50][50]; int n, m; // 0 up 1 right 2 down 3 left int x[4] = {-1, 0, 1, 0}; int y[4] = {0, 1
, 0, -1}; int vis[50][50]; bool inFiled(Node to) { if (to.x >= 0 && to.x < n && to.y >= 0 && to.y < m) return true; return false; } int dfs(Node now, int s) { if (_map[now.x][now.y] == 'E') return 1; for (int i = s, j = 0; j < 4; i = (i + (4 - s)) % 4
, j++) { Node to; to.path = (now.path + i) % 4; to.x = now.x + x[to.path]; to.y = now.y + y[to.path]; if (_map[to.x][to.y] != '#') return dfs(to, s) + 1; } return 0; } int bfs(Node s, Node e) { memset(vis, INF, sizeof(vis)); queue<Node> q; vis[s.x][s.y] = 1; q.push(s); while (!q.empty()) { Node top = q.front(); q.pop(); if (top.x == e.x && top.y == e.y) return top.path; for (int i = 0; i < 4; i++) { Node to; to.x = top.x + x[i]; to.y = top.y + y[i]; to.path = top.path + 1; if (inFiled(to) && _map[to.x][to.y] != '#' && vis[to.x][to.y] > to.path) { vis[to.x][to.y] = to.path; q.push(to); } } } return -1; } int main() { int t_case; scanf("%d", &t_case); for (int i_c = 0; i_c < t_case; i_c++) { scanf("%d%d", &m, &n); for (int i = 0; i < n; i++) scanf("%s", _map[i]); Node st, ed; for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { if (_map[i][j] == 'S') { st.x = i, st.y = j; } else if (_map[i][j] == 'E') { ed.x = i, ed.y = j; } } } st.path = 1; int minpath = bfs(st, ed); int leftpath, rightpath; for (int i = 3, j = 0; j < 4; i = (i + 1) % 4, j++) { Node to; to.path = i; to.x = st.x + x[to.path]; to.y = st.y + y[to.path]; if (inFiled(to) && _map[to.x][to.y] != '#') { leftpath = dfs(to, 3) + 1; break; } } for (int i = 1, j = 0; j < 4; i = (i + 3) % 4, j++) { Node to; to.path = i; to.x = st.x + x[to.path]; to.y = st.y + y[to.path]; if (inFiled(to) && _map[to.x][to.y] != '#') { rightpath = dfs(to, 1) + 1; break; } } printf("%d %d %d\n", leftpath, rightpath, minpath); } return 0; }