Ignatius再次被魔王抓走了(搞不懂他咋这么讨魔王喜欢)……
这次魔王汲取了上次的教训,把Ignatius关在一个n*m的地牢里,并在地牢的某些地方安装了带锁的门,钥匙藏在地牢另外的某些地方。刚开始Ignatius被关在(sx,sy)的位置,离开地牢的门在(ex,ey)的位置。Ignatius每分钟只能从一个坐标走到相邻四个坐标中的其中一个。魔王每t分钟回地牢视察一次,若发现Ignatius不在原位置便把他拎回去。经过若干次的尝试,Ignatius已画出整个地牢的地图。现在请你帮他计算能否再次成功逃亡。只要在魔王下次视察之前走到出口就算离开地牢,如果魔王回来的时候刚好走到出口或还未到出口都算逃亡失败。
Input
每组测试数据的第一行有三个整数n,m,t(2<=n,m<=20,t>0)。接下来的n行m列为地牢的地图,其中包括:
. 代表路
* 代表墙
@ 代表Ignatius的起始位置
^ 代表地牢的出口
A-J 代表带锁的门,对应的钥匙分别为a-j
a-j 代表钥匙,对应的门分别为A-J
每组测试数据之间有一个空行。
Output
针对每组测试数据,如果可以成功逃亡,请输出需要多少分钟才能离开,如果不能则输出-1。
Sample Input
4 5 17 @A.B. a*.*. *..*^ c..b* 4 5 16 @A.B. a*.*. *..*^ c..b*
Sample Output
16 -1
每次拿到钥匙后以前走过的路又可以继续走了,如果此时把vis清空,那么队列中还有其他没有拿这几种钥匙的情况,不可取,我们可以用一个2进制串来表示已经拿到的钥匙,每多拿一把钥匙就把二进制串更新,用一个新的vis来标记已走的结点
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<vector>
using namespace std;
char board[25][25];
int n,m,t,ans,vis[25][25][1026];
struct node1
{
int x,y;
node1(){}
node1(int x,int y):x(x),y(y){}
};
struct node
{
int x,y,dis,key;
node(){}
node(int x,int y,int dis,int key):x(x),y(y),dis(dis),key(key){}
}ff,en;
queue<node> qu;
int mov[4][2] = {{1,0},{0,1},{-1,0},{0,-1}};
inline int bfs()
{
while(!qu.empty())
{
node nown = qu.front();
qu.pop();
node nextn;
for(int i = 0;i < 4;++i)
{
nextn.x = nown.x + mov[i][0];
nextn.y = nown.y + mov[i][1];
nextn.dis = nown.dis + 1;
nextn.key = nown.key;
if(nextn.dis == t)
return -1;
if(nextn.x >= 1 && nextn.x <= n && nextn.y >= 1 && nextn.y <= m && !vis[nextn.x][nextn.y][nextn.key] && board[nextn.x][nextn.y] != '*')
{
if(board[nextn.x][nextn.y] == '^')
{
if(nextn.dis >= t)
return -1;
return nextn.dis;
}
if(board[nextn.x][nextn.y] <= 'J' && board[nextn.x][nextn.y] >= 'A')
{
if((1 << (board[nextn.x][nextn.y] - 'A')) & (nextn.key))
{
vis[nextn.x][nextn.y][nextn.key] = 1;
qu.push(nextn);
}
}
else if(board[nextn.x][nextn.y] <= 'j' && board[nextn.x][nextn.y] >= 'a')
{
int key=1<<(board[nextn.x][nextn.y]-'a');
if(!vis[nextn.x][nextn.y][nextn.key|key])
{
vis[nextn.x][nextn.y][nextn.key|key]=1;
nextn.key=nextn.key|key;
qu.push(nextn);
}
}
else
{
vis[nextn.x][nextn.y][nextn.key] = 1;
qu.push(nextn);
}
}
}
}
return -1;
}
int main()
{
while(~scanf("%d%d%d",&n,&m,&t))
{
while(!qu.empty())
qu.pop();
memset(vis,0,sizeof(vis));
for(int i = 1;i <= n;++i)
scanf("%s",board[i] + 1);
for(int i = 1;i <= n;++i)
{
for(int j = 1;j <= m;++j)
{
if(board[i][j] == '@')
{
ff.x = i;
ff.y = j;
ff.dis = 0;
}
if(board[i][j] == '^')
{
en.x = i;
en.y = j;
}
}
}
ff.dis = ff.key = 0;
vis[ff.x][ff.y][0] = 1;
qu.push(ff);
ans = bfs();
printf("%d\n",ans);
}
return 0;
}