题目链接
题目很好理解大家自己去看一下就好,大致思路就是bfs求出路径并且利用数组记录一下路径,b[nx][ny]=b[x][y]+1代表(x,y)是(nx,ny)的前缀,这个技巧很好用,从一个大佬那里学来的(heihei),然后我们需要从终点开始作为bfs的起点,并且记录路径,这样做的目的就是保证了我们记录的路径一定是可以到达终点的路径,然后我们利用dfs从(1,1)开始寻找字典序最小的路径,一次按顺序判断每个点四个方向的下一个点与前一个点的b数组的差值是否为1,满足就直接输出该方向,最后在输出的时候针对一些特殊情况进行判断,终点为1或者到不了终点这两种情况我们直接输出-1。
AC代码:
#include<bits/stdc++.h>
#define LL long long
#define PB push_back
#define POP pop_back()
#define PII pair<int,int>
#define FI first
#define SE second
#define ULL unsigned long long
#define endl '\n'
using namespace std;
const int INF=0x3f3f3f3f;
const double pi=acos(-1),eps=1e-8;
const int maxn=1<<17;
const int N=1e3+10,M=2e7+10,mod=998244353;
int n,m;
int a[N][N];
int b[N][N];
int dx[4]={-1,1,0,0};
int dy[4]={0,0,-1,1};
void bfs()
{
memset(b,-1,sizeof(b));
queue<PII>q;
q.push(PII(n,m));
b[n][m]=0;
while(!q.empty())
{
PII fr=q.front();
q.pop();
for(int i=0;i<4;i++)
{
int nx=fr.FI+dx[i],ny=fr.SE+dy[i];
if(nx>=1&&nx<=n&&ny>=1&&ny<=m&&a[nx][ny]==0&&b[nx][ny]==-1)
{
q.push(PII(nx,ny));
b[nx][ny]=b[fr.FI][fr.SE]+1;
}
}
}
}
void dfs(int x,int y)
{
if(x==n&&y==m)return;
int xx,yy;
xx=x+1,yy=y;
if(xx<=n&&b[xx][yy]==b[x][y]-1)
{
printf("D");
dfs(xx,yy);
return;
}
xx=x,yy=y-1;
if(yy>=1&&b[xx][yy]==b[x][y]-1)
{
printf("L");
dfs(xx,yy);
return;
}
xx=x,yy=y+1;
if(yy<=m&&b[xx][yy]==b[x][y]-1)
{
printf("R");
dfs(xx,yy);
return;
}
xx=x-1,yy=y;
if(xx>=1&&b[xx][yy]==b[x][y]-1)
{
printf("U");
dfs(xx,yy);
return;
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
scanf("%1d",&a[i][j]);
}
}
if(a[n][m]==1)
{
cout << -1 << endl;
return 0;
}
bfs();
if(b[1][1]==-1)
{
cout << -1 << endl;
return 0;
}
cout << b[1][1] << endl;
dfs(1,1);
return 0;
}