胜利大逃亡(续)
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 10266 Accepted Submission(s): 3720
Problem Description
Ignatius再次被魔王抓走了(搞不懂他咋这么讨魔王喜欢)……
这次魔王汲取了上次的教训,把Ignatius关在一个n*m的地牢里,并在地牢的某些地方安装了带锁的门,钥匙藏在地牢另外的某些地方。刚开始Ignatius被关在(sx,sy)的位置,离开地牢的门在(ex,ey)的位置。Ignatius每分钟只能从一个坐标走到相邻四个坐标中的其中一个。魔王每t分钟回地牢视察一次,若发现Ignatius不在原位置便把他拎回去。经过若干次的尝试,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
每组测试数据之间有一个空行。
. 代表路
* 代表墙
@ 代表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
这题需要判断的条件比较多,
其次就是需要状压记录携带的钥匙,
同时visit(book)数组需要设为三维的,以区分到达该点时携带不同钥匙的情况。
代码如下:
#include <iostream>
#include <cstring>
#include <queue>
#define maxn 25
using namespace std;
struct node{
int x,y,k,t; //x y:位置坐标 k:状压记录已携带钥匙 t:时间
}tmp,pre;
char m[maxn][maxn];
int v[maxn][maxn][1024],N,M,T;
int dir[4][2]={0,1,0,-1,1,0,-1,0};
int bfs()
{
queue<node>q;
q.push(tmp);
while(!q.empty())
{
pre=q.front();
q.pop();
for(int i=0;i<4;i++)
{
tmp.x=pre.x+dir[i][0];
tmp.y=pre.y+dir[i][1];
tmp.t=pre.t+1;
tmp.k=pre.k;
if(tmp.t>=T) return -1;
if(tmp.x<0||tmp.x>=N) continue;
if(tmp.y<0||tmp.y>=M) continue;
if(m[tmp.x][tmp.y]=='*') continue;
if(m[tmp.x][tmp.y]>='A'&&m[tmp.x][tmp.y]<='J'&&!(tmp.k&(1<<m[tmp.x][tmp.y]-'A'))) continue;
if(m[tmp.x][tmp.y]>='a'&&m[tmp.x][tmp.y]<='j') tmp.k|=1<<(m[tmp.x][tmp.y]-'a');
if(v[tmp.x][tmp.y][tmp.k]) continue;
if(m[tmp.x][tmp.y]=='^') return tmp.t;
v[tmp.x][tmp.y][tmp.k]=1;
q.push(tmp);
}
}
return -1;
}
int main()
{
while(cin>>N>>M>>T)
{
memset(v,0,sizeof(v));
for(int i=0;i<N;i++)
{
for(int j=0;j<M;j++)
{
cin>>m[i][j];
if(m[i][j]=='@')
{
tmp.x=i;
tmp.y=j;
tmp.k=0;
tmp.t=0;
}
}
}
cout<<bfs()<<endl;
}
return 0;
}