本题的题意是输入起点,朝向和终点,求一条最短路径(多解时任意输出一个即可)
本题的主要代码是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 }