bfs搜索。
首先儘量走0,bfs找到所有能走到的0。
如果已經可以到達終點當然不用做了。
如果不能到達,那麼從0上走到離終點最近的地方,再規定只能向右、向下走找路,且儘量使踩到的值小,可得到最優。。
恩,就醬。。。
#include<iostream>
#include<cstdio>
using namespace std;
int n,m;
int a[1010][1010];
int qx[1000010],qy[1000010];
bool used[1010][1010];
void bfs()
{
int l,r,i,j,x,y,be;
char ch;
for(i=0;i<=n+1;i++)
for(j=0;j<=m+1;j++)
used[i][j]=false;
l=1;r=1;used[1][1]=true;
qx[1]=1;qy[1]=1;
while(l<=r)
{
if(a[qx[l]][qy[l]]=='0')
{
x=qx[l];y=qy[l];
if(y+1<=m&&!used[x][y+1])
{
r++;qx[r]=x;qy[r]=y+1;used[x][y+1]=true;
}
if(y-1>=1&&!used[x][y-1])
{
r++;qx[r]=x;qy[r]=y-1;used[x][y-1]=true;
}
if(x+1<=n&&!used[x+1][y])
{
r++;qx[r]=x+1;qy[r]=y;used[x+1][y]=true;
}
if(x-1>=1&&!used[x-1][y])
{
r++;qx[r]=x-1;qy[r]=y;used[x-1][y]=true;
}
}
l++;
}
if(a[n][m]=='0'&&used[n][m]) printf("0\n");
else
{
be=0;
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
if(i+j>be&&used[i][j])
be=i+j;
printf("1");
for(i=be;i<n+m;i++)
{
ch='1';
for(j=1;j<=n;j++)
if(i-j>=1&&i-j<=m&&used[j][i-j])
{
if(a[j+1][i-j]<ch) ch=a[j+1][i-j];
if(a[j][i-j+1]<ch) ch=a[j][i-j+1];
}
printf("%c",ch);
for(j=1;j<=n;j++)
if(i-j>=1&&i-j<=m&&used[j][i-j])
{
if(a[j+1][i-j]==ch) used[j+1][i-j]=true;
if(a[j][i-j+1]==ch) used[j][i-j+1]=true;
}
}
printf("\n");
}
}
int main()
{
int t,i,j;
char ch;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++)
{
scanf("\n");
for(j=1;j<=m;j++)
scanf("%c",&a[i][j]);
}
for(i=1;i<=n;i++)
{
a[i][0]='2';
a[i][m+1]='2';
}
for(i=1;i<=m;i++)
{
a[0][i]='2';
a[n+1][i]='2';
}
bfs();
}
return 0;
}