如果没有相同字符,每次选向下和向右中较小的方向走。
如果有相同字符,我们可以枚举当前所有可能的位置,然后每次先算出答案中最小的字符是哪一个,然后用这个去更新所有可能的位置就行了。
#include<bits/stdc++.h>
using namespace std;
int rd()
{
int x=0;
char c=getchar();
bool f=false;
while(!isdigit(c))
f=(c=='-'),c=getchar();
while(isdigit(c))
x=x*10+c-48,c=getchar();
return f?-x:x;
}
char c[2001][2001];
bool v[2001][2001];
int pre[2001][2001];
char b[5001];
int n,m;
typedef pair<int,int> pii;
int main()
{
n=rd(),m=rd();
for(int i=1;i<=n;i++)
{
scanf("%s",c[i]+1);
}
queue<pair<int,int> >q;
q.push(make_pair(1,1));
v[1][1]=false;
for(int i=1;i<=n+m;i++)
b[i]='z';
b[2]=c[1][1];
while(!q.empty())
{
pii a=q.front();
q.pop();
int x=a.first,y=a.second;
if(b[x+y]<c[x][y])
continue;
if(y>m)
continue;
if(x>n)
continue;
if(x==n)
{
if(v[x][y+1])
continue;
if(b[x+y+1]<c[x][y+1])
continue;
else
b[x+y+1]=c[x][y+1];
q.push(make_pair(x,y+1));
v[x][y+1]=true;
continue;
}
if(y==m)
{
if(v[x+1][y])
continue;
if(b[x+y+1]<c[x+1][y])
continue;
else
b[x+y+1]=c[x+1][y];
q.push(make_pair(x+1,y));
v[x+1][y]=true;
continue;
}
if(c[x+1][y]>c[x][y+1])
{
if(v[x][y+1])
continue;
if(b[x+y+1]<c[x][y+1])
continue;
else
b[x+y+1]=c[x][y+1];
q.push(make_pair(x,y+1));
pre[x][y+1]=1;
v[x][y+1]=true;
continue;
}
if(c[x][y+1]>c[x+1][y])
{
if(v[x+1][y])
continue;
if(b[x+y+1]<c[x+1][y])
continue;
else
b[x+y+1]=c[x+1][y];
q.push(make_pair(x+1,y));
pre[x+1][y]=0;
v[x+1][y]=true;
continue;
}
if(b[x+y+1]<c[x][y+1])
continue;
if(!v[x+1][y])
{
v[x+1][y]=true;
pre[x+1][y]=0;
b[x+y+1]=c[x+1][y];
q.push(make_pair(x+1,y));
}
if(!v[x][y+1])
{
v[x][y+1]=true;
pre[x][y+1]=1;
b[x+y+1]=c[x][y+1];
q.push(make_pair(x,y+1));
}
}
for(int i=2;i<=n+m;i++)
printf("%c",b[i]);
return 0;
}