zoukankan      html  css  js  c++  java
  • UVA-816.Abbott's Tevenge (BFS + 打印路径)

      本题大意:给定一个迷宫,让你判断是否能从给定的起点到达给定的终点,这里起点需要输入起始方向,迷宫的每个顶点也都有行走限制,每个顶点都有特殊的转向约束...具体看题目便知...

      本题思路:保存起点和终点的状态,保存每个顶点的状态,包括每个方向的可转向方向,然后直接BFS即可,记得保存每个儿子结点的爹,便于回溯输出路径。

      参考代码:

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 
      4 struct Node{
      5     int r, c, dir;// 表示结点的横纵坐标和方向
      6     Node(int r = 0, int c = 0, int dir = 0) :r(r), c(c), dir(dir) {};//对结构体元素进行初始化
      7 };
      8 const int maxn = 10;
      9 const char *dirs = "NESW";
     10 const char *turns = "FLR";
     11 const int dr[] = {-1, 0, 1, 0};
     12 const int dc[] = {0, 1, 0, -1};
     13 int has_edge[maxn][maxn][4][3];//保存(r, c, dir)状态下的可移动方向
     14 int d[maxn][maxn][4];//存储初始状态到(r, c, dir)的最短路长度
     15 Node p[maxn][maxn][4];//同时用p[r][c][dir]保存了状态(r, c, dir)在BFS树中的父节点
     16 int r0, c0, dir, r1, c1, r2, c2;
     17 char name[99];
     18 
     19 int dir_id(char c) {
     20     return strchr(dirs, c) - dirs;
     21 }
     22 
     23 int turn_id(char c) {
     24     return strchr(turns, c) - turns;
     25 }
     26 
     27 Node walk(const Node &u, int turn) {
     28     int dir = u.dir;
     29     if(turn == 1) dir = (dir + 3) % 4;//逆时针
     30     if(turn == 2) dir = (dir + 1) % 4;//顺时针
     31     return Node(u.r + dr[dir], u.c + dc[dir], dir);
     32 }
     33 
     34 bool inside(int r, int c) {
     35     return r >= 1 && r <= 9 && c >= 1 && c <=9;
     36 }
     37 
     38 bool read_case () {
     39     char s[99], s2[99];
     40     scanf("%s", name);
     41     if(!strcmp(name, "END")) return false;
     42     scanf("%d %d %s %d %d", &r0, &c0, s2, &r2, &c2);
     43     cout << name << endl;
     44     dir = dir_id(s2[0]);
     45     r1 = r0 + dr[dir];
     46     c1 = c0 + dc[dir];
     47     memset(has_edge, 0, sizeof(has_edge));
     48     while(true) {
     49         int r, c;
     50         scanf("%d", &r);
     51         if(r == 0) break;
     52         scanf("%d", &c);
     53         while(~scanf("%s", s) && s[0] != '*') {
     54             for(int i = 1; i < strlen(s); i ++)
     55                 has_edge[r][c][dir_id(s[0])][turn_id(s[i])] = 1;
     56         }
     57     }
     58     return true;
     59 }
     60 
     61 void print_ans(Node u) {
     62     //从目标节点逆序回溯到初始结点
     63     vector <Node> nodes;
     64     while(true) {
     65         nodes.push_back(u);
     66         if(d[u.r][u.c][u.dir] == 0) break;
     67         u = p[u.r][u.c][u.dir];
     68     }
     69     nodes.push_back(Node(r0, c0, dir));
     70     //打印解,每行10个
     71     int cnt = 0;
     72     for(int i = nodes.size() - 1; i >= 0; i --) {
     73         if(cnt % 10 == 0) printf(" ");
     74             printf(" (%d,%d)", nodes[i].r, nodes[i].c);
     75         if(++ cnt % 10 == 0)    printf("
    ");
     76     }
     77     if(nodes.size() % 10 != 0) printf("
    ");
     78 }
     79 
     80 void solve () {
     81     queue <Node> q;
     82     memset(d, -1, sizeof(d));
     83     Node u(r1, c1, dir);
     84     d[u.r][u.c][u.dir] = 0;
     85     q.push(u);
     86     while(!q.empty()) {
     87         Node u = q.front();
     88         q.pop();
     89         if(u.r == r2 && u.c == c2) {
     90             print_ans(u);
     91             return;
     92         }
     93         for(int i = 0; i < 3; i ++) {
     94             Node v = walk(u, i);
     95             if(has_edge[u.r][u.c][u.dir][i] && inside(v.r, v.c) && d[v.r][v.c][v.dir] < 0) {
     96                 d[v.r][v.c][v.dir] = d[u.r][u.c][u.dir] + 1;
     97                 p[v.r][v.c][v.dir] = u;
     98                 q.push(v);
     99             }
    100         }
    101     }
    102     printf("  No Solution Possible
    ");
    103 }
    104 
    105 int main () {
    106     while(read_case()) {
    107         solve();
    108     }
    109     return 0;
    110 }
    View Code
  • 相关阅读:
    bzoj3993: [SDOI2015]星际战争
    bzoj3583: 杰杰的女性朋友 && 4362: Graph
    bzoj2260: 商店购物 && 4349: 最小树形图
    老oj3444 && Pku3241 Object Clustering
    bzoj3754: Tree之最小方差树
    bzoj2215: [Poi2011]Conspiracy
    老oj曼哈顿最小生成树
    bzoj2180: 最小直径生成树
    棋盘问题
    油田 Oil Deposits
  • 原文地址:https://www.cnblogs.com/bianjunting/p/10539975.html
Copyright © 2011-2022 走看看