题意:
给出一个(2*m-1)*(2*n-1)的图,要求输出从左下角走到右上角最短距离走法的路径,只能在 ‘-’ 或 ‘|’ 上移动,答案保证有解,有多解输出任一,n,m<=400。
思路:
因为题目要求输出路径,而bfs中如果每个状态都记录到当前状态的路径,可能会TLE或者MLE。
所以考虑先从终点开始bfs出每个点到终点的最短距离,然后再从起点出发bfs一直找 当前点的最短距离-1==下一步的最短距离 的位置就可以回到终点,注意方向的变换。
代码:
#include<bits/stdc++.h>
using namespace std;
char mp[1005][1005];
int dis[1005][1005];
int m,n;
int dx[10]={-1,0,1,0}; //反向由北到西顺时针 依次为0123
int dy[10]={0,1,0,-1};
int dd[10][10] = {
{0, 1, 2, 3}, // F
{3, 0, 1, 2}, // L
{1, 2, 3, 0} // R
};
char dir[10]={'F','L','R'};
struct node
{
int x,y;
node(){}
node(int x,int y):x(x),y(y){}
};
void bfs()
{
queue<node>q;
memset(dis,-1,sizeof(dis));
dis[1][2*n-1]=0;
q.push(node(1,2*n-1));
node now;
int x,y,px,py;
while(!q.empty())
{
now=q.front();
q.pop();
px=now.x,py=now.y;
//printf("%d %d\n",px,py);
for(int i=0;i<4;i++)
{
x=px+dx[i];
y=py+dy[i];
if(mp[x][y]=='-' || mp[x][y]=='|')
{
x+=dx[i];
y+=dy[i];
if(dis[x][y]==-1)
{
dis[x][y]=dis[px][py]+1;
q.push(node(x,y));
}
}
}
}
}
void print()
{
int statu,x,y,px,py;
if(mp[2*m-1][2]=='-' && dis[2*m-1][1]-1==dis[2*m-1][3])
{
puts("E");
px=2*m-1,py=3;
statu=1;
}
else if(mp[2*m-2][1]=='|' && dis[2*m-1][1]-1==dis[2*m-3][1])
{
puts("N");
px=2*m-3,py=1;
statu=0;
}
while(1)
{
if(dis[px][py]==0)
{
puts("");
break;
}
for(int i=0;i<3;i++)
{
x=px+dx[dd[i][statu]];
y=py+dy[dd[i][statu]];
if(mp[x][y]=='-' || mp[x][y]=='|')
{
x+=dx[dd[i][statu]];
y+=dy[dd[i][statu]];
if(dis[x][y]==dis[px][py]-1)
{
printf("%c",dir[i]);
statu=dd[i][statu];
px=x,py=y;
break;
}
}
}
}
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&m,&n);
memset(mp,' ',sizeof(mp));
getchar();
for(int i=1; i<=2*m-1; i++)
{
gets(mp[i]+1);
}
bfs();
/*for(int i=1;i<=2*m-1;i+=2)
{
for(int j=1;j<=2*n-1;j+=2)
{
printf("%3d",dis[i][j]);
}puts("");
}*/
print();
if(T) puts("");
}
}
/*
2
4 4
+-+-+-+
|
+-+-+-+
|
+-+-+-+
|
+-+-+-+
N
RFFLLFFRRFF
4 4
+-+ +-+
| | |
+ +-+-+
| | |
+-+-+-+
| |
+-+-+-+
E
FFLFF
*/