UVA 816 Abbott's Revenge(2000 Final)
2014-10-18 20:32
330 查看
题意:
有一个最多包涵9*9个交叉点的迷宫。输入起点,离开起点时的朝向和终点,求一条最短路。
思路:
这个迷宫的特殊之处在于:进入一个交叉点的方向不同,那么允许出去的方式也不同。而且朝向起到了关键的作用。所以要用一个三元组(r,c,dir)表示位于(r,c)面朝dir这个状态。由于初始时第一步怎么走是确定的,因此要从X1,Y1开始BFS,而不是X0,Y0。由于要打印路径,因此要记录前驱。
有一个最多包涵9*9个交叉点的迷宫。输入起点,离开起点时的朝向和终点,求一条最短路。
思路:
这个迷宫的特殊之处在于:进入一个交叉点的方向不同,那么允许出去的方式也不同。而且朝向起到了关键的作用。所以要用一个三元组(r,c,dir)表示位于(r,c)面朝dir这个状态。由于初始时第一步怎么走是确定的,因此要从X1,Y1开始BFS,而不是X0,Y0。由于要打印路径,因此要记录前驱。
#include <queue> #include <vector> #include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> using namespace std; struct node{ int x,y; int w; void init(int nx, int ny, int nw){ x = nx; y = ny; w = nw; } }p[10][10][4]; int X0,Y0,X1,Y1,W1,SX,SY; int dir[4][3][2] ={{-1, 0, 0, -1, 0, 1}, {0, 1, -1, 0, 1, 0}, {1, 0, 0, 1, 0, -1}, {0, -1, 1, 0, -1, 0} };///移动数组 int map[10][10][4],vis[10][10][4]; int id(char c){ if(c == 'N' || c == 'F') return 0; else if(c == 'E' || c == 'L') return 1; else if(c == 'S' || c == 'R') return 2; else return 3; } void print(int x, int y, int w); int bfs(int x, int y, int w){ queue <node> q; while(!q.empty()) q.pop(); node a,b; a.init(x, y, w); vis[a.x][a.y][a.w] = 0; q.push(a); while(!q.empty()){ a = q.front(); q.pop(); if(a.x == SX && a.y == SY){ print(a.x, a.y, a.w); return 1; } int xx, yy, ww; for(int i=0; i<3; i++){ xx = a.x, yy = a.y, ww = a.w; xx += dir[a.w][i][0]; yy += dir[a.w][i][1]; if(i == 1) ww = (ww + 3) % 4;///用数字间的关系模拟向左转 else if(i == 2) ww = (ww + 1) % 4; b.init(xx, yy, ww); if((map[a.x][a.y][a.w]) & (1 << i)){///a & pow(2,n)检测a的第n位是否为1,是返回正数,否则返回假 if(xx < 1 || xx > 9 || yy < 1 || yy > 9) continue; if(vis[xx][yy][ww] >= 0) continue; vis[xx][yy][ww] = vis[a.x][a.y][a.w] + 1; p[xx][yy][ww] = a;///记录前驱即父亲节点以打印路径 q.push(b); } } } return 0; } void print(int x, int y, int w){///用动态数组打印路径 vector <node> v; node a,b; a.init(x, y, w); v.push_back(a); while(vis[a.x][a.y][a.w]){ a = p[a.x][a.y][a.w]; v.push_back(a); } a.init(X0, Y0, W1); v.push_back(a); int cnt = 0; for(int i=v.size() - 1; i >=0; i--){ if(cnt % 10 == 0) cout << " ";///控制输出十列 cout << " (" << v[i].x << "," << v[i].y << ")"; if(++cnt % 10 == 0) cout << endl; } if(v.size() % 10) cout << endl; } int main(){ // freopen("in.txt", "r", stdin); char str[30]; while(cin >> str){ if(!strcmp(str, "END")) break; cout << str << endl; memset(map, 0, sizeof(map)); memset(vis, -1, sizeof(vis)); char c; cin >> X0 >> Y0 >> c >> SX >> SY; W1 = id(c); X1 = X0 + dir[W1][0][0]; Y1 = Y0 + dir[W1][0][1]; int xx,yy; while(cin >> xx && xx){ cin >> yy; gets(str); int i = 1, j = id(str[1]); while(str[i++] != '*'){ if(str[i] == ' '){ j = id(str[++i]); continue; } map[xx][yy][j] ^= (1 << id(str[i]));///a ^ pow(2,n)是将a的第n位取反 } } if(!bfs(X1, Y1, W1)) cout << " No Solution Possible" << endl; } return 0; }
相关文章推荐
- Abbott 的复仇(Abbott's Revenge,ACM|IPPC World Finals 2000, UVa 816)
- UVA 816 - Abbott's Revenge(BFS)
- UVA - 816 Abbott's Revenge
- UVa816 Abbott's Revenge
- UVa 816 Abbott's Revenge(状态压缩BFS)
- uva 816 - Abbott's Revenge(有点困难bfs迷宫称号)
- UVa 816 - Abbott's Revenge(BFS+记录状态判重)
- uva 816 - Abbott's Revenge(有一点难度的bfs迷宫题目)
- uva 816 Abbott's Revenge (走迷宫BFS)
- UVa816 例题 6-14 Abbott的复仇 (Abbott's Revenge,ACM/ICPC World Finals 2000)
- Abbott的复仇(Abbott's Revenge, ACM/ICPC World Finals 2000, UVa 816)<经典BFS>
- Abbott 的复仇(Abbott's Revenge,ACM|IPPC World Finals 2000, UVa 816)
- 816 - Abbott's Revenge(BFS)
- 例题6-14 Abbott的复仇(Abbott's Revenge, ACM/ICPC World Finals 2000, UVa 816)
- UVa816 Abbott's Revenge
- Uva - 816 - Abbott's Revenge