[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;
}

  

原文地址:https://www.cnblogs.com/jerryRey/p/4596875.html