• 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
    ");
     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 }
  • 相关阅读:
    win7与centos虚拟机的共享文件夹创建
    MySQL视图
    MySQL分区表与合并表
    PHP读写XML文件的四种方法
    备份与恢复
    MySQL日志
    MySQL锁问题
    优化数据库对象
    ActiveReport资料
    对ArrayList 进行深拷贝
  • 原文地址:https://www.cnblogs.com/zyb993963526/p/6286736.html
Copyright © 2020-2023  润新知