分析:
一个很显然的暴力是设dis[x][y][p][q]记录yyb和空格的坐标,每次bfs一遍。
可以发现,如果你想要移动点(x,y),那么空格一定要在(x,y)边上。对于yyb,显然你只关心她的位置和空格的位置。而空格总要在yyb边上才能发挥作用。
考虑预处理一下这个东西:f[i][j][p][q]表示在不动i,j的情况下,将空格从(i,j)的p方向移动到q方向至少需要多少步。然后,对于每次询问,设dis[x][y][p]表示yyb在(x,y),空格在她的p方向上。只有两种转移:1.yyb移动到空格上;2.空格移动到yyb的另一侧。因为预处理了f数组,我们可以快速计算出第二种转移的代价。于是,复杂度就变成了O((n*m)^2*16+q*最短路(n*m*4))。
需要注意的是,在一开始的时候,空格不一定在yyb边上。所以需要先bfs求出把空格移动到yyb身边各个方向分别需要多少时间,再跑多源最短路即可。
(我又犯懒了......)
代码:
(可能与分析不符,但思路是差不多的。)
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <queue>
#include <utility>
typedef std::pair<int,int> Pair;
int n,m,q,a[35][35],dx[5]={0,-1,1,0,0},dy[5]={0,0,0,-1,1};
int dis[35][35],dis2[4005],head[4005],ecnt;
bool vis[35][35],book[4005];
struct Edge{
int to,nxt,w;
}e[5005];
inline void add_edge(int bg,int ed,int val){
ecnt++;
e[ecnt].to=ed;
e[ecnt].nxt=head[bg];
e[ecnt].w=val;
head[bg]=ecnt;
}
std::queue<Pair> q1;
std::queue<int> q2;
inline void bfs(int sx,int sy,int tx,int ty,int typ){
memset(vis,0,sizeof vis);
while(!q1.empty()) q1.pop();
dis[sx][sy]=0;
vis[sx][sy]=1;
q1.push((Pair){sx,sy});
while(!q1.empty()){
int x=q1.front().first,y=q1.front().second;q1.pop();
for(int i=1;i<=4;i++){
int xx=x+dx[i],yy=y+dy[i];
if(!vis[xx][yy]&&!(xx==tx&&yy==ty)&&a[xx][yy]){
dis[xx][yy]=dis[x][y]+1;
vis[xx][yy]=1;
q1.push((Pair){xx,yy});
}
}
}
if(typ==5) return;
for(int i=1;i<=4;i++){
int xx=tx+dx[i],yy=ty+dy[i];
if(!vis[xx][yy]||(xx==sx&&yy==sy)) continue;
add_edge(((tx-1)*31+ty)*4+typ-1,((tx-1)*31+ty)*4+i-1,dis[xx][yy]);
}
add_edge(((tx-1)*31+ty)*4+typ-1,((sx-1)*31+sy)*4+(typ%2==1?typ:typ-2),1);
}
inline void spfa(int sx,int sy){
memset(dis2,0x3f,sizeof dis2);
while(!q2.empty()) q2.pop();
for(int i=1;i<=4;i++){
int xx=sx+dx[i],yy=sy+dy[i];
if(!vis[xx][yy]) continue;
dis2[((sx-1)*31+sy)*4+i-1]=dis[xx][yy];
q2.push(((sx-1)*31+sy)*4+i-1);
book[((sx-1)*31+sy)*4+i-1]=1;
}
while(!q2.empty()){
int u=q2.front();
for(int i=head[u];i;i=e[i].nxt){
int ver=e[i].to;
if(dis2[ver]>dis2[u]+e[i].w){
dis2[ver]=dis2[u]+e[i].w;
if(!book[ver]){
q2.push(ver);
book[ver]=1;
}
}
}
q2.pop();
book[u]=0;
}
}
int main(){
scanf("%d%d%d",&n,&m,&q);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
scanf("%d",&a[i][j]);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++){
if(!a[i][j]) continue;
if(a[i-1][j]) bfs(i-1,j,i,j,1);
if(a[i+1][j]) bfs(i+1,j,i,j,2);
if(a[i][j-1]) bfs(i,j-1,i,j,3);
if(a[i][j+1]) bfs(i,j+1,i,j,4);
}
while(q--){
int ex,ey,sx,sy,tx,ty;
scanf("%d%d%d%d%d%d",&ex,&ey,&sx,&sy,&tx,&ty);
if(sx==tx&&sy==ty){
printf("0\n");
continue;
}
bfs(ex,ey,sx,sy,5);
spfa(sx,sy);
int ans=1e9;
for(int i=1;i<=4;i++)
ans=std::min(ans,dis2[((tx-1)*31+ty)*4+i-1]);
if(ans==1e9) printf("-1\n");
else printf("%d\n",ans);
}
return 0;
}