zoukankan      html  css  js  c++  java
  • [uva816]AbbottsRevenge Abbott的复仇(经典迷宫BFS)

    这题思路就普通的BFS加上一个维度朝向,主要是要注意输入,输出,以及细节的处理

    #include<cstdio>
    #include<cstring>
    #include<queue>
    #include<vector>
    using namespace std;
    
    const int MAX = 9+1;
    const int DIR = 4;
    const int TURN = 3;
    bool have_edge[MAX][MAX][DIR][TURN];//所在位置 , 朝向 , 要走的方向
    
    int d[MAX][MAX][DIR];//最短路径 同时可以判断结点是否访问过
    #define Node(x,n) x[n.r][n.c][n.dir]
    
    struct node
    {
       int r , c, dir;
       node(){}
       node(int r, int c, int dir):r(r),c(c),dir(dir){}
    };
    
    struct node p[MAX][MAX][DIR];//父节点 打印 路径
    const char *dirs = "NESW";//clockwise
    const char *turns = "LFR";
    
    inline int dir_id(char c) {return strchr(dirs,c)-dirs;}
    inline int turn_id(char c) {return strchr(turns,c)-turns;}
    
    const int MAX_NAME_LEN = 42;
    char MazeName[MAX_NAME_LEN];//20个字符,还有空格。。。
    int r0,c0;
    int r1,c1,dir1;
    int r2,c2;
    int dr[] = {-1, 0, 1, 0};//clockwise
    int dc[] = { 0, 1, 0,-1};
    
    bool read()
    {
       gets(MazeName);//lineread
       //  if(!strcmp(MazeName,"END")) return false;
       char s[10]; int r, c;
       if(!~scanf("%d%d%s",&r0,&c0,s)) return false;
       printf("%s
    ",MazeName);
       memset(have_edge,false,sizeof(have_edge));
    
       dir1 = dir_id(s[0]);
       r1 = r0 + dr[dir1]; c1 = c0 + dc[dir1];
       scanf("%d%d",&r2,&c2);
    
       while(scanf("%d",&r),r) {
          scanf("%d",&c);
          while(scanf("%s",s),*s != '*'){
             char *p = s; int dir = dir_id(*s);//!!
             while(*(++p)) { have_edge[r][c][dir][turn_id(*p)] = true;}
          }
       }
       getchar();//吸收换行符
       return true;
    }
    
    void print_ans(node u)
    {
       vector<node> ans;
       for(;;){
          ans.push_back(u);
          if(Node(d,u) == 0) break;
          u = Node(p,u);
       }
       ans.push_back(node(r0,c0,dir1));
       int cnt = 0;
       for(int i = ans.size() - 1; i >= 0; i--){
          if(cnt%10 == 0) printf(" ");
          printf(" (%d,%d)", ans[i].r, ans[i].c);
          if(++cnt%10 == 0) puts("");
       }
       if(ans.size()%10) puts("");//注意
    }
    
    node walk(node &u,int turn){
       int dir = u.dir;
       if(turn == 0) dir = (dir + 3)%4;//rev 
       else if(turn == 2) dir = (dir + 1)%4;//clockwise
       return node(u.r + dr[dir], u.c + dc[dir], dir );
    }
    inline bool inside(int r,int c) { return r > 0&&r <= 9 && c > 0 && c <= 9; }
    
    
    
    void solve()
    {
       queue<node> q;
       node u(r1,c1,dir1);//c1 - >c2
       memset(d, -1, sizeof(d));
       d[u.r][u.c][u.dir] = 0;
       q.push(u);
       while(!q.empty()){
          u = q.front();q.pop();
          if(u.r == r2 && u.c == c2) { print_ans(u); return ;}
          for(int i = 0; i < 3; i++) {
             if(!have_edge[u.r][u.c][u.dir][i]) continue;
             node v = walk(u,i);
             if(inside(v.r, v.c) && d[v.r][v.c][v.dir] < 0){
                d[v.r][v.c][v.dir] = Node(d,u) + 1;
                Node(p,v) = u;
                q.push(v);//push(u) ...
             }
          }
       }
       printf("  No Solution Possible
    ");
    }
    
    int main()
    {
    #ifdef local
       freopen("in2.txt","r",stdin);
      // freopen("myout.txt","w",stdout);
    #endif // local
       while(read()){
          solve();
       }
       return 0;
    }
    

      

  • 相关阅读:
    第二十九课 循环链表的实现
    第二十八课 再论智能指针(下)
    第二十七课 再论智能指针(上)
    第二十六课 典型问题分析(Bugfix)
    普通new和placement new的重载
    leetcode 581. Shortest Unsorted Continuous Subarray
    leetcode 605. Can Place Flowers
    leetcode 219. Contains Duplicate II
    leetcode 283. Move Zeroes
    leetcode 217. Contains Duplicate
  • 原文地址:https://www.cnblogs.com/jerryRey/p/4596875.html
Copyright © 2011-2022 走看看