-
4 4 2 0 0 0 3 .A.B .#.. .#.. .#.. 3 0 3 3
样例输出
-
15
描述
小Hi正处在由 N × M 个房间组成的矩阵迷宫中。为了描述方便,我们把左上角的房间的坐标定为(0, 0),右下角房间的坐标定为(N-1, M-1)。每个房间可能是3种状态之一:开放的、关闭的、或者上锁的。
开放房间用'.'表示。小Hi可以从一个开放房间到达另一个相邻的(上下左右)开放房间。
关闭房间用'#'表示。小Hi永远不能进入一个关闭的房间。
上锁的房间用大写字母('A', 'B', 'C' ...)表示。小Hi在取得相应的钥匙前不能进入上锁的房间,而一旦取得钥匙就可以反复进入上锁的房间。每个房间的锁都是不同的,相应的钥匙在迷宫中的某一房间里,小Hi进入该房间就可以取得钥匙。
小Hi一开始处于一个开放房间,坐标(a, b)。迷宫的出口是一个开放或者上锁的房间,坐标(c, d)。假设小Hi每移动到一个相邻房间需要花费单位1的时间,那么小Hi到达出口最少需要花费多少时间?
输入
第一行包含7个整数: N , M , K , a , b , c , d . 其中N , M是矩阵的行列数;K 是上锁的房间数目,(a, b)是起始位置,(c, d)是出口位置。(1 ≤ N, M ≤ 100, 0 ≤ K ≤ 5, 0 ≤ a, c < N, 0 ≤ b, d < M)
以下 N 行每行包含 M 个字符,表示迷宫矩阵。
再以下 K 行每行两个整数 x, y,依次表示上锁房间A , B , C ....的钥匙所在房间坐标。(0 ≤ x < N, 0 ≤ y < M)
输出
输出到达出口的最短时间。如果小Hi永远到达不了出口,输出-1。
#include<cstdio>
#include<queue>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
struct lenka
{
int x,y,sum;
}key[10];
char s[105][105];
int v[105][105][1<<6];
int d[4][2]={-1,0,0,-1,1,0,0,1};
int n,m,ex,ey;
int bfs(int nx,int ny)
{
memset(v,0,sizeof v);
v[nx][ny][0]=1;
queue<struct lenka>p;
p.push((lenka){nx,ny,0});
while(!p.empty())
{
lenka now=p.front();p.pop();
if(now.x==ex&&now.y==ey)return v[now.x][now.y][now.sum]-1;
for(int i=0;i<4;i++)
{
nx=now.x+d[i][0];
ny=now.y+d[i][1];
if(nx>=0&&nx<n&&ny>=0&&ny<m&&s[nx][ny]!='#')
{
if(s[nx][ny]=='.'&&v[nx][ny][now.sum]==0)
{
v[nx][ny][now.sum]=v[now.x][now.y][now.sum]+1;
p.push((lenka){nx,ny,now.sum});
}
else if('0'<=s[nx][ny]&&s[nx][ny]<='5')
{
int sum=now.sum|(1<<(s[nx][ny]-'0'));
if(v[nx][ny][sum])continue;
v[nx][ny][sum]=v[now.x][now.y][now.sum]+1;
p.push((lenka){nx,ny,sum});
}
else if(s[nx][ny]>='A'&&s[nx][ny]<='Z')
{
if(now.sum&(1<<(s[nx][ny]-'A'))&&v[nx][ny][now.sum]==0)
{
v[nx][ny][now.sum]=v[now.x][now.y][now.sum]+1;
p.push((lenka){nx,ny,now.sum});
}
}
}
}
}
return -1;
}
int main()
{
int sx,sy,T;
scanf("%d%d%d%d%d%d%d",&n,&m,&T,&sx,&sy,&ex,&ey);
for(int i=0;i<n;i++)scanf("%s",s[i]);
for(int i=0;i<T;i++)
{
scanf("%d%d",&key[i].x,&key[i].y);
s[key[i].x][key[i].y]='0'+i;
}
printf("%d\n",bfs(sx,sy));
return 0;
}