Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 12020 | Accepted: 5168 |
Description
Input
Output
Sample Input
2 8 8 ######## #......# #.####.# #.####.# #.####.# #.####.# #...#..# #S#E#### 9 5 ######### #.#.#.#.# S.......E #.#.#.#.# #########
Sample Output
37 5 5 17 17 9
最后一问求最短路直接BFS,前面两个DFS比较好写,不用标记,找到为止,重点在DFS时候的搜索的优先级顺序,靠左墙和靠右墙的时候只是优先级顺序不同,递归的其他
地方都一样,用一个参数pos(pos是地图的绝对方向)将上一步的方向传进去,以绝对方向来讨论表示走的时候的相对上一步的方向
以靠右墙走为例
u: 上 r: 右 d: 下 l: 左
上一步 下一步优先级
u r,u,l,d
r d,r,u,l
d l,d,r,u
l u,l,d,r
靠左墙走直接复制粘贴改改就行了
把情况都枚举出来的,代码略长
#include <cstdio> #include <cstring> #include <iostream> #include <queue> using namespace std; int n, m, sx, sy, ex, ey; char mapp[50][50]; bool vis[50][50], vismo[50][50]; int dis[4][2] = {-1, 0, 0, -1, 1, 0, 0, 1}; struct node { int x, y; int step; node() {} node(int x, int y, int step) : x(x), y(y), step(step) {} }; queue<node> Q; bool check(int x, int y) { if (x < 0 || x >= n || y < 0 || y >= m || vis[x][y]) return false; return true; } int cc = 0; bool dfsl(int step, char dir, int x, int y) { if (step > 1600) return false; if (x == ex && y == ey) { printf("%d ", step); return true; } if (dir == 'u') { /* 不要写成 if (!vis[x][y - 1]) { if (dfsl(step + 1, 'l', x, y - 1)) { return true; } } 否则发现第一个不行,下一步其他的方向就不会再试了 */ if (!vis[x][y - 1] && dfsl(step + 1, 'l', x, y - 1)) { //左 return true; } else if (!vis[x - 1][y] && dfsl(step + 1, 'u', x - 1, y)) { //上 return true; } else if (!vis[x][y + 1] && dfsl(step + 1, 'r', x, y + 1)) { //右 return true; } else if (!vis[x + 1][y] && dfsl(step + 1, 'd', x + 1, y)) { //下 return true; } } else if (dir == 'd') { if (!vis[x][y + 1] && dfsl(step + 1, 'r', x, y + 1)) { //右 return true; } else if (!vis[x + 1][y] && dfsl(step + 1, 'd', x + 1, y)) { //下 return true; } else if (!vis[x][y - 1] && dfsl(step + 1, 'l', x, y - 1)) { //左 return true; } else if (!vis[x - 1][y] && dfsl(step + 1, 'u', x - 1, y)) { //上 return true; } } else if (dir == 'l') { if (!vis[x + 1][y] && dfsl(step + 1, 'd', x + 1, y)) { //下 return true; } else if (!vis[x][y - 1] && dfsl(step + 1, 'l', x, y - 1)) { //左 return true; } else if (!vis[x - 1][y] && dfsl(step + 1, 'u', x - 1, y)) { //上 return true; } else if (!vis[x][y + 1] && dfsl(step + 1, 'r', x, y + 1)) { //右 return true; } } else if (dir == 'r') { if (!vis[x - 1][y] && dfsl(step + 1, 'u', x - 1, y)) { //上 return true; } else if (!vis[x][y + 1] && dfsl(step + 1, 'r', x, y + 1)) { //右 return true; } else if (!vis[x + 1][y] && dfsl(step + 1, 'd', x + 1, y)) { //下 return true; } else if (!vis[x][y - 1] && dfsl(step + 1, 'l', x, y - 1)) { //左 return true; } } } //copy->paste bool dfsr(int step, char dir, int x, int y) { if (step > 1600) return false; if (x == ex && y == ey) { printf("%d ", step); return true; } if (dir == 'u') { if (!vis[x][y + 1] && dfsr(step + 1, 'r', x, y + 1)) { //右 return true; } else if (!vis[x - 1][y] && dfsr(step + 1, 'u', x - 1, y)) { //上 return true; } else if (!vis[x][y - 1] && dfsr(step + 1, 'l', x, y - 1)) { //左 return true; } else if (!vis[x + 1][y] && dfsr(step + 1, 'd', x + 1, y)) { //下 return true; } } else if (dir == 'd') { if (!vis[x][y - 1] && dfsr(step + 1, 'l', x, y - 1)) { //左 return true; } else if (!vis[x + 1][y] && dfsr(step + 1, 'd', x + 1, y)) { //下 return true; } else if (!vis[x][y + 1] && dfsr(step + 1, 'r', x, y + 1)) { //右 return true; } else if (!vis[x - 1][y] && dfsr(step + 1, 'u', x - 1, y)) { //上 return true; } } else if (dir == 'l') { if (!vis[x - 1][y] && dfsr(step + 1, 'u', x - 1, y)) { //上 return true; } else if (!vis[x][y - 1] && dfsr(step + 1, 'l', x, y - 1)) { //左 return true; } else if (!vis[x + 1][y] && dfsr(step + 1, 'd', x + 1, y)) { //下 return true; } else if (!vis[x][y + 1] && dfsr(step + 1, 'r', x, y + 1)) { //右 return true; } } else if (dir == 'r') { if (!vis[x + 1][y] && dfsr(step + 1, 'd', x + 1, y)) { //下 return true; } else if (!vis[x][y + 1] && dfsr(step + 1, 'r', x, y + 1)) { //右 return true; } else if (!vis[x - 1][y] && dfsr(step + 1, 'u', x - 1, y)) { //上 return true; } else if (!vis[x][y - 1] && dfsr(step + 1, 'l', x, y - 1)) { //左 return true; } } } void bfss() { memcpy(vis, vismo, sizeof(vis)); while(!Q.empty()) Q.pop(); Q.push(node(sx, sy, 1)); vis[sx][sy] = true; while (!Q.empty()) { node tn = Q.front(); Q.pop(); for (int i = 0; i < 4; i++) { int nx = tn.x + dis[i][0]; int ny = tn.y + dis[i][1]; if (nx == ex && ny == ey) { printf("%d\n", tn.step + 1); return ; } if (check(nx, ny)) { vis[nx][ny] = true; Q.push(node(nx, ny, tn.step + 1)); } } } } int main() { int T; scanf("%d", &T); //?? while (T--) { memset(vismo, false, sizeof(vismo)); scanf("%d%d", &m, &n); for (int i = 0; i < n; i++) { scanf("%s", mapp[i]); for (int j = 0; j < m; j++) { if (mapp[i][j] == '#') vismo[i][j] = true; if (mapp[i][j] == 'S') { sx = i; sy = j; } if (mapp[i][j] == 'E'){ ex = i; ey = j; } } } //用一个只读的vismo,怕深广搜标记乱了 //然而除了广搜并不用标记,用不用都可以 memcpy(vis, vismo, sizeof(vis)); char pos; int nx, ny; for (int i = 0; i < 4; i++) { nx = sx + dis[i][0]; ny = sy + dis[i][1]; if (check(nx, ny)) { switch(dis[i][0]) { case 1: pos = 'd'; break; case -1: pos = 'u'; break; default: break; } switch(dis[i][1]) { case 1: pos = 'r'; break; case -1: pos = 'l'; break; default: break; } dfsl(2, pos, nx, ny); break; } } memcpy(vis, vismo, sizeof(vis)); dfsr(2, pos, nx, ny); bfss(); } return 0; }