UVa 816 Abbott的复仇(BFS)
Posted 谦谦君子,陌上其华
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UVa 816 Abbott的复仇(BFS)相关的知识,希望对你有一定的参考价值。
寒假的第一道题目,在放假回家颓废了两天后,今天终于开始刷题了。希望以后每天也能多刷几道题。
题意:这道BFS题还是有点复杂的,给一个最多9*9的迷宫,但是每个点都有不同的方向,每次进入该点的方向不同,允许出去的方向也不同。所以在记录迷宫的时候比较麻烦,可以用一个四元组has_edge[10][10][4][4]来记录,前两个元素代表坐标点,第三个元素代表进入该点时的方向,第四个元素代表离开该点时的方向。在BFS遍历时还是和以前的题目差不多的,记录好路径,最后回溯输出就行。
我还犯了个小错误,因为我用的是getline来输入每个迷宫的名字,所以在每次while循环最后应该加一句getchar()来吃掉回车。不然第二次循环时字符串就是回车了,这样就出错了。
1 #include<iostream> 2 #include<string> 3 #include<cstring> 4 #include<queue> 5 #include<vector> 6 using namespace std; 7 8 struct node 9 { 10 int rr, cc, dir; 11 node(int a, int b, int c) { rr = a; cc = b; dir = c; } 12 node(){} 13 }; 14 15 string str; 16 17 int r0,c0,r1,c1,r2,c2; 18 char dir; 19 20 const char* dirs = "NESW"; 21 const char* turns = "FLR"; 22 23 int dir_id(char c) { return strchr(dirs, c) - dirs; } //查找字符串中首次出现c的位置 24 int turn_id(char c) { return strchr(turns, c) - turns; } 25 26 const int dr[] = { -1, 0, 1, 0 }; 27 const int dc[] = { 0, 1, 0, -1 }; 28 29 int has_edge[10][10][4][4]; 30 31 int d[10][10][4]; 32 node v[10][10][4]; 33 34 node walk(const node &u, int turn) 35 { 36 int dir = u.dir; 37 if (turn == 1) dir = (dir + 3) % 4; 38 if (turn == 2) dir = (dir + 1) % 4; 39 return node(u.rr + dr[dir], u.cc + dc[dir], dir); 40 } 41 42 bool inside(int x, int y) 43 { 44 if (x<10 && x>0 && y<10 && y>0) 45 return true; 46 return false; 47 } 48 49 void printfff(node u) 50 { 51 vector<node> nodes; 52 for (;;) 53 { 54 nodes.push_back(u); 55 if (d[u.rr][u.cc][u.dir] == 0) break; 56 u = v[u.rr][u.cc][u.dir]; 57 } 58 nodes.push_back(node(r0, c0, dir_id(dir))); 59 60 int cnt = 0; 61 for (int i = nodes.size() - 1; i >= 0; i--) 62 { 63 if (cnt % 10 == 0) printf(" "); 64 printf(" (%d,%d)", nodes[i].rr, nodes[i].cc); 65 if (++cnt % 10 == 0) cout << endl; 66 } 67 if (nodes.size() % 10 != 0) cout << endl; 68 } 69 70 void BFS() 71 { 72 queue<node> q; 73 memset(d, -1, sizeof(d)); 74 node p(r1, c1, dir_id(dir)); 75 d[p.rr][p.cc][p.dir] = 0; 76 q.push(p); 77 while (!q.empty()) 78 { 79 node p = q.front(); 80 q.pop(); 81 if (p.rr == r2 && p.cc == c2) 82 { 83 printfff(p); 84 return; 85 } 86 for (int k = 0; k < 3; k++) 87 { 88 node r = walk(p, k); 89 if (has_edge[p.rr][p.cc][p.dir][k] && inside(r.rr, r.cc) && d[r.rr][r.cc][r.dir]<0) 90 { 91 d[r.rr][r.cc][r.dir] = d[p.rr][p.cc][p.dir] + 1; 92 v[r.rr][r.cc][r.dir] = p; 93 q.push(r); 94 } 95 } 96 } 97 printf(" No Solution Possible\n"); 98 } 99 100 101 int main() 102 { 103 int x, y; 104 while (getline(cin,str) && str!= "END") 105 { 106 cout << str << endl; 107 memset(has_edge, 0, sizeof(has_edge)); 108 cin >> r0 >> c0 >> dir >> r2 >> c2; 109 r1 = r0 + dr[dir_id(dir)]; //计算出初始位置点 110 c1 = c0 + dc[dir_id(dir)]; 111 while (cin >> x && x != 0) 112 { 113 cin >> y; 114 char ch[50]; 115 while (cin >> ch && ch[0] != ‘*‘) 116 { 117 int DIR = dir_id(ch[0]); 118 int l = strlen(ch); 119 for (int i = 1; i < l; i++) 120 { 121 int TURN = turn_id(ch[i]); 122 has_edge[x][y][DIR][TURN] = 1; 123 } 124 } 125 } 126 BFS(); 127 getchar(); 128 } 129 return 0; 130 }
以上是关于UVa 816 Abbott的复仇(BFS)的主要内容,如果未能解决你的问题,请参考以下文章