[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\n",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\n"); } int main() { #ifdef local freopen("in2.txt","r",stdin); // freopen("myout.txt","w",stdout); #endif // local while(read()){ solve(); } return 0; }