这道题目结合了深搜和广搜,利用深搜求得最左边走和最右边走的个数,利用广搜求得最短路径,这里注意三个问题:
1)深搜时要把握方向,每一次都有一个面朝向(共有四种朝向),每一种朝向向左走和向右走的顺序都不一样,但要注意每种朝向都是最后走与该朝向背向的方向。
2)注意深搜时方向一定不要写错,否则可能会TLE
3)注意广搜时要剪枝,否则也会TLE
下面是代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <queue>
using namespace std;
#define Max 50
bool flag[Max][Max];
bool trag[Max][Max];
int Case;
int w,h;
int Llen,Rlen;
int startx,starty,endx,endy;
char start_dir;
typedef struct Node{
int x;
int y;
int deep;
}node;
void Ldfs(char dir,int x,int y,int deep){
if(x==endx && y==endy){
Llen=deep;
return ;
}
switch(dir){
case 'N':
if(y-1>=1 && flag[x][y-1])
Ldfs('W',x,y-1,deep+1);
else if(x-1>=1 && flag[x-1][y])
Ldfs('N',x-1,y,deep+1);
else if(y+1<=w && flag[x][y+1])
Ldfs('E',x,y+1,deep+1);
else
Ldfs('S',x+1,y,deep+1);
break;
case 'S':
if(y+1<=w && flag[x][y+1])
Ldfs('E',x,y+1,deep+1);
else if(x+1<=h && flag[x+1][y])
Ldfs('S',x+1,y,deep+1);
else if(y-1>=1 && flag[x][y-1])
Ldfs('W',x,y-1,deep+1);
else
Ldfs('N',x-1,y,deep+1);
break;
case 'W':
if(x+1<=h && flag[x+1][y])
Ldfs('S',x+1,y,deep+1);
else if(y-1>=1 && flag[x][y-1])
Ldfs('W',x,y-1,deep+1);
else if(x-1>=1 && flag[x-1][y])
Ldfs('N',x-1,y,deep+1);
else
Ldfs('E',x,y+1,deep+1);
break;
default:
if(x-1>=1 && flag[x-1][y])
Ldfs('N',x-1,y,deep+1);
else if(y+1<=w && flag[x][y+1])
Ldfs('E',x,y+1,deep+1);
else if(x+1<=h && flag[x+1][y])
Ldfs('S',x+1,y,deep+1);
else
Ldfs('W',x,y-1,deep+1);
break;
}
}
void Rdfs(char dir,int x,int y,int deep){
if(x==endx && y==endy){
Rlen=deep;
return ;
}
switch(dir){
case 'N':
if(y+1<=w && flag[x][y+1])
Rdfs('E',x,y+1,deep+1);
else if(x-1>=1 && flag[x-1][y])
Rdfs('N',x-1,y,deep+1);
else if(y-1>=1 && flag[x][y-1])
Rdfs('W',x,y-1,deep+1);
else
Rdfs('S',x+1,y,deep+1);
break;
case 'S':
if(y-1>=1 && flag[x][y-1])
Rdfs('W',x,y-1,deep+1);
else if(x+1>=1 && flag[x+1][y])
Rdfs('S',x+1,y,deep+1);
else if(y+1<=w && flag[x][y+1])
Rdfs('E',x,y+1,deep+1);
else
Rdfs('N',x-1,y,deep+1);
break;
case 'W':
if(x-1>=1 && flag[x-1][y])
Rdfs('N',x-1,y,deep+1);
else if(y-1>=1 && flag[x][y-1])
Rdfs('W',x,y-1,deep+1);
else if(x+1<=h && flag[x+1][y])
Rdfs('S',x+1,y,deep+1);
else
Rdfs('E',x,y+1,deep+1);
break;
default:
if(x+1<=h && flag[x+1][y])
Rdfs('S',x+1,y,deep+1);
else if(y+1<=w && flag[x][y+1])
Rdfs('E',x,y+1,deep+1);
else if(x-1>=1 && flag[x-1][y])
Rdfs('N',x-1,y,deep+1);
else
Rdfs('W',x,y-1,deep+1);
break;
}
}
int bfs(){
//int count=1;
memset(trag,0,sizeof(trag));
queue<node> Queue;
node Point;
Point.x=startx;
Point.y=starty;
Point.deep=1;
Queue.push(Point);
trag[startx][starty]=1;
int x,y,count;
while(!Queue.empty()){
Point = Queue.front();
Queue.pop();
if(Point.x==endx && Point.y==endy)
return Point.deep;
x=Point.x,y=Point.y;
count=Point.deep;
if(x-1>=1 && flag[x-1][y] && !trag[x-1][y]){
Point.x=x-1;
Point.y=y;
Point.deep=count+1;
trag[x-1][y]=1;
Queue.push(Point);
}
if(x+1<=h && flag[x+1][y] && !trag[x+1][y]){
Point.x=x+1;
Point.y=y;
Point.deep=count+1;
trag[x+1][y]=1;
Queue.push(Point);
}
if(y-1>=1 && flag[x][y-1] && !trag[x][y-1]){
Point.x=x;
Point.y=y-1;
Point.deep=count+1;
trag[x][y-1]=1;
Queue.push(Point);
}
if(y+1<=w && flag[x][y+1] && !trag[x][y+1]){
Point.x=x;
Point.y=y+1;
Point.deep=count+1;
trag[x][y+1]=1;
Queue.push(Point);
}
}
}
int main(){
scanf("%d",&Case);
while(Case--){
scanf("%d%d",&w,&h);
memset(flag,0,sizeof(flag));
char temp;
for(int i=1;i<=h;i++){
getchar();
for(int j=1;j<=w;j++){
temp=getchar();
if(temp=='.')
flag[i][j]=1;
else if(temp=='S'){
if(i==1)
start_dir='S';
else if(i==h)
start_dir='N';
else if(j==1)
start_dir='E';
else if(j==w)
start_dir='W';
startx=i;
starty=j;
}
else if(temp=='E'){
endx=i;
endy=j;
flag[i][j]=1;
}
}
}
//printf("%d %d\n",startx,starty);
Ldfs(start_dir,startx,starty,1);
//printf("%d\n",Llen);
Rdfs(start_dir,startx,starty,1);
printf("%d %d %d\n",Llen,Rlen,bfs());
}
return 0;
}