BFS求最短路 Abbottt's Revenge UVa 816

本题的题意是输入起点,朝向和终点,求一条最短路径(多解时任意输出一个即可)

本题的主要代码是bfs求解,就是以下代码中的slove的主要部分,通过起点按照路径的长度来寻找最短路径,输出最先到终点的一系列点

以下代码中,用两个数组保存四个方向,运用函数walk()表示结点的方向变换,通过d[][][]保存路径的长度,p[][][]保存路径中的结点,has_edge[][][][]标记行得通的路径,同时用队列先进先出,层次遍历所有结点,用vector存储将要输出的结点,防止内存空间不够大

  1 #include<stdio.h>
  2 #include<queue>
  3 #include<string>
  4 #include<string.h>
  5 #include<vector>
  6 #include<iostream>
  7 using namespace std;
  8 const int maxn=20;
  9 char name[25];
 10 int r0,c0,r1,c1,r2,c2,dir,turn;
 11 char dir0,str[5];
 12 int has_edge[maxn][maxn][maxn][maxn];   //表示当前状态,是否可以沿turn的方向行走
 13 int d[maxn][maxn][maxn];                //表示初始状态到(r1,c1,dir)的最短路的长度
 14 string maze_name;
 15 
 16 const char* dirs="NESW";
 17 const char* turns="FLR";
 18 const int dr[]={-1,0,1,0};      //
 19 const int dc[]={0,1,0,-1};      //
 20 int dir_id(char c){return strchr(dirs,c)-dirs;}
 21 int turn_id(char c){return strchr(turns,c)-turns;}
 22 
 23 struct Node{
 24     int dir,r,c;
 25     Node(int r=0,int c=0,int dir=0):r(r),c(c),dir(dir){}
 26 };
 27 
 28 Node p[maxn][maxn][maxn];           //保存状态
 29 
 30 Node walk(const Node& u,int turn){
 31     int dir=u.dir;
 32     if(turn==1) dir=(dir+3)%4;          //逆时针
 33     if(turn==2) dir=(dir+1)%4;          //顺时针
 34     return Node(u.r+dr[dir],u.c+dc[dir],dir);
 35 }
 36 
 37 bool inside(int r,int c){
 38     if(r>=1&&r<=9&&c>=1&&c<=9)  return true;
 39     return false;
 40 }
 41 
 42 
 43 
 44 void print_ans(Node u){
 45     vector<Node> nodes;
 46     for(;;){
 47         nodes.push_back(u);
 48         if(d[u.r][u.c][u.dir]==0)   break;
 49         u=p[u.r][u.c][u.dir];
 50     }
 51     nodes.push_back(Node(r0,c0,dir));
 52     int cnt=0;
 53     for(int i=nodes.size()-1;i>=0;i--){
 54         if(cnt%10==0)   printf(" ");
 55          printf(" (%d,%d)",nodes[i].r,nodes[i].c);
 56         if(++cnt%10==0) printf("
");
 57        // printf("(%d,%d)%c",nodes[i].r,nodes[i].c,++cnt%10?' ':'
');
 58     }
 59     if(nodes.size()%10!=0)  printf("
");
 60 }
 61 
 62 
 63 void solve(){
 64     memset(d,-1,sizeof(d));
 65     queue<Node> q;
 66     d[r1][r2][dir]=0;
 67     Node u(r1,c1,dir);
 68     q.push(u);
 69     while(!q.empty()){
 70         u=q.front();
 71         q.pop();
 72         if(u.r==r2&&u.c==c2){
 73             print_ans(u);
 74             return;
 75         }
 76         for(int i=0;i<3;i++){
 77             Node v=walk(u,i);
 78             if(d[v.r][v.c][i]<0&&inside(v.r,v.c)&&has_edge[u.r][u.c][u.dir][i]){
 79                 d[v.r][v.c][v.dir]=d[u.r][u.c][u.dir]+1;
 80                 p[v.r][v.c][v.dir]=u;
 81                 q.push(v);
 82             }
 83         }
 84     }
 85     printf("No Solution Possible
");
 86 }
 87 
 88 
 89 
 90 int main(){
 91     freopen("in.txt","r",stdin);
 92     while(scanf("%s",name)){
 93         memset(has_edge,0,sizeof(has_edge));
 94         if(strcmp(name,"END")==0)  break;
 95         scanf("%d%d",&r0,&c0);
 96         scanf("%s",&dir0);
 97         scanf("%d%d",&r2,&c2);
 98         dir=dir_id(dir0);
 99          r1=r0+dr[dir];
100         c1=c0+dc[dir];
101         int pr,pc,pdir,pturn;
102         while(scanf("%d",&pr)&&pr){
103             scanf("%d",&pc);
104             while(scanf("%s",str)){
105                 if(str[0]=='*'){break;}
106                 pdir=dir_id(str[0]);
107                 int len=strlen(str);
108                 for(int i=1;i<len;i++){
109                     pturn=turn_id(str[i]);
110                     has_edge[pr][pc][pdir][pturn]=1;
111                 }
112             }
113         }
114         cout<<name<<endl;
115         solve();
116     }
117     return 0;
118 }
原文地址:https://www.cnblogs.com/muziqiu/p/7267215.html