Description
Input
Output
Sample Input
2 8 8 ######## #......# #.####.# #.####.# #.####.# #.####.# #...#..# #S#E#### 9 5 ######### #.#.#.#.# S.......E #.#.#.#.# #########
Sample Output
37 5 5 17 17 9
一道题,从学图到做出来,花了一天。
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<iostream> 5 #include<queue> 6 using namespace std; 7 int s[50][50],vis[50][50]; 8 int si,sj,ei,ej; 9 int r[4]= {0,0,1,-1};//这个是访问上下左右 10 int c[4]= {1,-1,0,0}; 11 struct node 12 { 13 int i,j,step; 14 } p,ph; 15 int ri[12]= {1,0,-1,0,1,0,-1,0,1,0,-1,0};//这个是为了方便转方向,具体用途刚才解释过 16 int rj[12]= {0,-1,0,1,0,-1,0,1,0,-1,0,1}; 17 queue<node>que; 18 void get(int a,int b) 19 { 20 int i,j; 21 char ch; 22 for(i=1; i<a; i++) 23 { 24 for(j=1; j<b; j++) 25 { 26 scanf("%c",&ch);//这是一个简单地输入转换 27 if(ch=='#') 28 s[i][j]=0; 29 else 30 { 31 if(ch=='S') 32 { 33 si=i; 34 sj=j; 35 } 36 if(ch=='E') 37 { 38 ei=i; 39 ej=j; 40 } 41 s[i][j]=1; 42 } 43 } 44 getchar();//去掉换行符 45 } 46 } 47 void bfs()//广度优先搜索,找最短路径 48 { 49 int k,a,b; 50 p.i=si,p.j=sj,p.step=1; 51 que.push(p);//入栈 52 memset(vis,0,sizeof(vis)); 53 vis[si][sj]=1; 54 while(!que.empty()) 55 { 56 p=que.front();//取栈顶元素 57 que.pop();//取后弹出 58 for(k=0; k<4; k++) 59 { 60 a=p.i+r[k],b=p.j+c[k]; 61 if(a==ei&&b==ej)//是要找的就返回 62 { 63 printf("%d\n",p.step+1); 64 return; 65 } 66 if(!vis[a][b]&&s[a][b])//如果未被访问过,又是可以可以走的路,就入栈 67 { 68 ph.i=a,ph.j=b,ph.step=p.step+1; 69 que.push(ph); 70 vis[a][b]=1; 71 } 72 } 73 } 74 } 75 void lr(char ch)//解决靠左靠右走的问题,合并了 76 { 77 int k,i,j,ia=si,ja=sj,ib,jb,step=1; 78 for(k=0; k<4; k++)//第一步只有一种走法 79 { 80 if(s[ia+r[k]][ja+c[k]]) 81 { 82 ib=ia+r[k]; 83 jb=ja+c[k]; 84 break; 85 } 86 } 87 while(1)//直到找到正确的路再返回 88 { 89 if(ib==ei&&jb==ej)//找到正确的路返回 90 { 91 printf("%d ",++step); 92 return ; 93 } 94 step++; 95 i=ib-ia,j=jb-ja; 96 ia=ib,ja=jb; 97 for(k=3; k<8; k++)//没有的话,这里确定方向 98 if(ri[k]==i&&rj[k]==j) 99 break; 100 if(ch=='R')//看是左优先还是右优先 101 { 102 k++; 103 if(s[ib+ri[k]][jb+rj[k]])//判断右侧是不是路,是就走 104 { 105 ib+=ri[k],jb+=rj[k]; 106 continue; 107 } 108 for(k=k-1; k>0; k--)//不是依次向左找路 109 if(s[ib+ri[k]][jb+rj[k]]) 110 { 111 ib+=ri[k],jb+=rj[k]; 112 break; 113 } 114 } 115 else//参考向右的 116 { 117 k--; 118 if(s[ib+ri[k]][jb+rj[k]]) 119 { 120 ib+=ri[k],jb+=rj[k]; 121 continue; 122 } 123 for(k=k+1;; k++) 124 if(s[ib+ri[k]][jb+rj[k]]) 125 { 126 ib+=ri[k],jb+=rj[k]; 127 break; 128 } 129 } 130 } 131 } 132 int main() 133 { 134 int p,a,b; 135 cin>>p; 136 getchar(); 137 while(p--) 138 { 139 memset(s,0,sizeof(s)); 140 cin>>b>>a; 141 getchar();//输入不解释,其实主函数最简单 不解释了 142 get(a+1,b+1); 143 lr('L'); 144 lr('R'); 145 bfs(); 146 } 147 return 0; 148 }