问题 3744 --隐蔽的角落(完善程序)

3744: 隐蔽的角落(完善程序)★★★★

时间限制: 1 Sec  内存限制: 128 MB
提交: 35  解决: 25
[提交][状态][命题人:]

题目描述

        大侦探forever97进入了一个大小为N*M的迷宫,迷宫的出口有一把上锁的门,需要钥匙才能打开。钥匙被藏在迷宫内的一个隐蔽的角落,幸运的是,大侦探forever97知道隐蔽的角落在哪里。如果只是这样,那这个角落一点也不隐蔽。角落的隐蔽之处在于,迷宫内布置了不少传送阵,当forever97在传送阵所在的格子上时,可以选择不启动传送阵留在原地,或者花费一个单位时间启动传送阵瞬间传送到迷宫内一个指定地方,这使得forever97很容易着迷于他喜欢的传送阵,或直接被传送到墙内而被挤死,从而错过寻找钥匙。
        现在forever97想知道,他最少需要花费多少单位时间,才能找到钥匙并从出口离开。
        迷宫可以用N*M的格子表示,每个格子用字符'x'或字符'#'表示,'x'字符表示没有障碍物可以行动,'#'字符表示有障碍物无法行动。forever97可以花费一个单位时间,从当前格子向上下左右四个方向前进一格到没有障碍物的格子上。
        迷宫的入口在(1,1)处,出口在(N,M)处,钥匙在(x0,y0)处。保证forever97能找到钥匙从出口离开迷宫。
        迷宫共有p个传送阵,第i个传送阵在(ai,bi)处,可以传送到(ci,di)处,保证同一格子上只有一个传送阵,但多个传送阵可能传送到同一格子。
#include<bits/stdc++.h>
using namespace std;

const int MAXN=55;
char mz[MAXN][MAXN];
int cx[MAXN][MAXN],cy[MAXN][MAXN];
int vis[2][MAXN][MAXN];
int g[2][4]={{-1,0,0,1},{0,1,-1,0}};

struct Node
{
	int x,y,key,step;
	Node(){}
	Node(int _x,int _y,int _key,int _step)
	{
		x=_x,y=_y,key=_key,step=_step;
	}
};

int main()
{
	int n,m,x0,y0,p,a,b,c,d,ans,i,j;
	while(cin>>n>>m)
	{
		cin>>x0>>y0>>p;
		memset(vis,0,sizeof(vis));
		memset(cx,-1,sizeof(cx));
		memset(cy,-1,sizeof(cy));
		while(p--)
		{
			cin>>a>>b>>c>>d;
			cx[a][b]=c;
			cy[a][b]=d;
		}
		for(i=1;i<=n;i++)
			for(j=1;j<=m;j++)
				cin>>mz[i][j];
		queue<Node>q;
		if(x0==1&&y0==1)
			q.push(Node(1,1,1,0)),vis[1][1][1]=1;
		else
			q.push(__(1)__),vis[0][1][1]=0;
		while(!q.empty())
		{
			Node now=q.front();
			q.pop();
			if(now.key&&now.x==n&&now.y==m)
			{
				__(2)__
				break;
			}
			for(i=0;i<5;i++)
			{
				__(3)__
				if(i<4)
					nxt.x+=g[0][i],nxt.y+=g[1][i];
				else if(cx[now.x][now.y])
					nxt.x=cx[now.x][now.y],nxt.y=cy[now.x][now.y];
				else
					__(4)__
				nxt.step++;
				if(nxt.x==x0&&nxt.y==y0)
					nxt.key=1;
				if(nxt.x<1||nxt.x>n||nxt.y<1||nxt.y>m||vis[nxt.key][nxt.x][nxt.y]||mz[nxt.x][nxt.y]=='#')
					continue;
				__(5)__
				vis[nxt.key][nxt.x][nxt.y]=1;
			}
		}
		cout<<ans<<endl;
	}
}

输入

输入包含一组测试数据。
第一行包含两个正整数N和M(1≤N,M≤50)。
第二行包含两个正整数x0和y0(1≤x0≤N,1≤Y0≤M),表示钥匙所在处。
第三行包含一个正整数p(1≤p≤N*M)。
接下来p行,每行包含四个正整数ai,bi,ci,di(1≤ai,ci≤N,1≤bi,di≤M)。
最后N行,每行包含M个字符,表示迷宫。

输出

输出一行,包含一个整数,表示forever97至少需要花费多少单位时间,才能找到钥匙后从出口离开。
样例输入
Copy
5 5
1 5
1
5 1 2 5
xxx#x
x#x#x
x#x#x
x#x#x
x#xxx
样例输出
Copy
10

提示

请注意在保证至少存在一条找到钥匙后从出口离开迷宫的方法的情况下,一切满足数据范围内的数据均有可能出现。

来源

[提交][状态]