首页 > 代码库 > UVa 816 Abbott的复仇(BFS)

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)