题目大意:
#include <cstdio>
#include <algorithm>
#include <queue>
#define N 505
#define M 600005
#define INF 1000000000
using namespace std;
const int xx[]={-1,0,1,0},yy[]={0,-1,0,1};
inline bool isdigit(const char& c) { return c>='0' && c<='9'; }
struct Point {
int x,y;
Point() {}
Point(int _x,int _y):x(_x),y(_y) {}
bool operator == (const Point& rhs) const { return x==rhs.x && y==rhs.y; }
}pos[10],to[N][N][4],s[N*N];
queue<Point> q1,q2;
int n,m,p,top,dfs_clock,f[10][10][N][N],mark[N][N][4];
char mp[N][N];
Point dfs(int x,int y,int dir) {
if(mark[x][y][dir]==dfs_clock) return Point(-1,-1);
mark[x][y][dir]=dfs_clock;
if(to[x][y][dir].y) return to[x][y][dir];
int ndir=dir;
if(mp[x][y]=='A') ndir++;
if(mp[x][y]=='C') ndir+=3;
if(ndir>3) ndir-=4;
int nx=x+xx[ndir], ny=y+yy[ndir];
if(nx<1 || nx>n || ny<1 || ny>m || mp[nx][ny]=='x')
return to[x][y][dir]=Point(x,y);
return to[x][y][dir]=dfs(nx,ny,ndir);
}
void SPFA(int l,int r) {
static bool inq[N][N];
static int sum[M];
static Point tmp[N*N];
int maxx=-INF,minn=INF;
for(int i=1;i<=top;i++) {
int& val=f[l][r][s[i].x][s[i].y];
sum[val]++;
maxx=max(maxx,val), minn=min(minn,val);
inq[s[i].x][s[i].y]=true;
}
for(int i=minn+1;i<=maxx;i++) sum[i]+=sum[i-1];
for(int i=1;i<=top;i++) {
int& val=f[l][r][s[i].x][s[i].y];
tmp[sum[val]--]=s[i];
}
for(int i=1;i<=top;i++) s[i]=tmp[top-i+1];
for(int i=minn;i<=maxx;i++) sum[i]=0;
while(top) q1.push(s[top--]);
while(!q1.empty() || !q2.empty()) {
Point o;
if(q1.empty()) o=q2.front(), q2.pop();
else if(q2.empty()) o=q1.front(), q1.pop();
else {
Point o1=q1.front(),o2=q2.front();
if(f[l][r][o1.x][o1.y]<f[l][r][o2.x][o2.y]) o=o1, q1.pop();
else o=o2, q2.pop();
}
inq[o.x][o.y]=false;
for(int i=0;i<4;i++) {
Point no=to[o.x][o.y][i];
if(no==Point(-1,-1) || f[l][r][o.x][o.y]+1>=f[l][r][no.x][no.y]) continue;
f[l][r][no.x][no.y]=f[l][r][o.x][o.y]+1;
if(!inq[no.x][no.y]) inq[no.x][no.y]=true, q2.push(no);
}
}
return ;
}
int main() {
scanf("%d%d%d",&p,&m,&n);
for(int l=0;l<=p;l++)
for(int r=0;r<=p;r++)
for(int x=0;x<=n;x++)
for(int y=0;y<=m;y++)
f[l][r][x][y]=INF;
for(int i=1;i<=n;i++) scanf("%s",mp[i]+1);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++) {
if(!isdigit(mp[i][j])) continue;
int x=mp[i][j]-'0';
pos[x]=Point(i,j);
f[x][x][i][j]=0;
}
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
if(mp[i][j]!='x')
for(int k=0;k<4;k++)
dfs_clock++, to[i][j][k]=dfs(i,j,k);
for(int i=1;i<=p;i++) s[++top]=pos[i], SPFA(i,i);
for(int len=2;len<=p;len++)
for(int l=1,r;(r=l+len-1)<=p;l++) {
for(int x=1;x<=n;x++)
for(int y=1;y<=m;y++) {
for(int k=l;k<r;k++)
f[l][r][x][y]=min(f[l][r][x][y],f[l][k][x][y]+f[k+1][r][x][y]);
if(f[l][r][x][y]!=INF)
s[++top]=Point(x,y);
}
SPFA(l,r);
}
int ans=INF;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
ans=min(ans,f[1][p][i][j]);
if(ans==INF) ans=-1;
printf("%d\n",ans);
return 0;
}