记录编号 313357 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 [NOIP 2013]华容道 最终得分 100
用户昵称 GravatarFoolMike 是否通过 通过
代码语言 C++ 运行时间 0.669 s
提交时间 2016-09-29 14:34:37 内存使用 0.40 MiB
显示代码纯文本
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int N=1010,maxl=99999999;
int n,m,q,f[50][50];
int dist[N][4][4];
struct point{
	int x,y;
	point(int X=0,int Y=0){x=X;y=Y;}
	inline bool operator == (const point &X){
		return x==X.x&&y==X.y;
	}
	inline point operator + (const point &X){
		return point(x+X.x,y+X.y);
	}
}v[4]={point(1,0),point(-1,0),point(0,1),point(0,-1)};
inline bool check(point x){return x.x>0&&x.x<=n&&x.y>0&&x.y<=m&&f[x.x][x.y];}
inline int P(point x){return (x.x-1)*m+x.y;}
int dis[N];
void clear(){
	for (int i=1;i<=n;i++)
	for (int j=1;j<=m;j++)
		dis[P(point(i,j))]=maxl;
}
void bfs1(point x){
	dis[P(x)]=0;
	queue<point> Q;
	Q.push(x);
	while (!Q.empty()){
		point x=Q.front();int now=P(x);Q.pop();
		for (int i=0;i<4;i++){
			point t=x+v[i];int pos=P(t);
			if (check(t)&&dis[now]+1<dis[pos])
				dis[pos]=dis[now]+1,Q.push(t);
		}
	}
}
int D[N][4];bool vis[N][4];
struct sit{
	point x;int p,d;
	sit(point X=point(0,0),int pos=0){x=X;p=pos;d=D[P(x)][p];}
	bool operator > (const sit &x)const{return d>x.d;}
};
void dijsktra(point S,point T){
	for (int i=1;i<=n;i++)
	for (int j=1;j<=m;j++)
	for (int k=0;k<4;k++)
		D[P(point(i,j))][k]=maxl;
	memset(vis,0,sizeof vis);
	priority_queue<sit,vector<sit>,greater<sit> > Q;
	for (int k=0;k<4;k++){
		point t=S+v[k];
		if (check(t)) D[P(S)][k]=dis[P(t)],Q.push(sit(S,k));
	}
	while (!Q.empty()){
		sit x=Q.top();int now=P(x.x),p=x.p;Q.pop();
		if (vis[now][p]) continue;
		if (x.x==T) return;
		for (int k=0;k<4;k++){//将棋子沿着向量v[k]移动 
			point t=x.x+v[k];int to=(k&1?k-1:k+1),pos=P(t);
			if (!check(t)) continue;
			if (D[pos][to]>D[now][p]+dist[now][p][k]+1){
				D[pos][to]=D[now][p]+dist[now][p][k]+1;
				Q.push(sit(t,to));
			}
		}
	}
}
int main()
{
	freopen("PuzzleNOIP2013.in","r",stdin);
	freopen("PuzzleNOIP2013.out","w",stdout);
	scanf("%d%d%d",&n,&m,&q);
	for (int i=1;i<=n;i++)
	for (int j=1;j<=m;j++)
		scanf("%d",&f[i][j]);
	for (int i=1;i<=n;i++)
	for (int j=1;j<=m;j++){
		point x(i,j);int now=P(x);
		if (!check(x)) continue;
		for (int k=0;k<4;k++){
			point t=x+v[k];
			if (!check(t)) continue;
			clear();dis[P(x)]=-1;bfs1(t);
			for (int l=0;l<4;l++) dist[now][k][l]=dis[P(x+v[l])];
		}
	}
	while (q--){
		int a,b,c,d,e,f;
		scanf("%d%d%d%d%d%d",&a,&b,&c,&d,&e,&f);
		point E(a,b),S(c,d),T(e,f);
		if (S==T){puts("0");continue;}
		clear();dis[P(S)]=-1;bfs1(E);dijsktra(S,T);
		int ans=maxl;
		for (int k=0;k<4;k++) ans=min(ans,D[P(T)][k]);
		printf("%d\n",ans==maxl?-1:ans);
	}
	return 0;
}