Description
话说
CZ
由于不守基道,被妖怪抓走了,好基友
WP
在努力讨好高富帅
RQ
救出
CZ
的同时,
CZ
也意识到了自己的错误,然后努力的想逃出妖怪的闺房。
Input
每组测试数据的第一行有三个整数
n,m,t(2<=n,m<=20,t>0)。接下来的
n行
m列为闺房的地图,其中包括
:
. 代表路
* 代表墙
@ 代表CZ的起始位置
^ 代表闺房的出口
A-J 代表带锁的门,对应的钥匙分别为a-j
a-j 代表钥匙,对应的门分别为A-J
. 代表路
* 代表墙
@ 代表CZ的起始位置
^ 代表闺房的出口
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
Hint
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int n,m,t1;
char map[30][30];
int a[30][30][1100];
struct node
{
int x,y,z,step;
} q[1000000],t,f;
int jx[]= {0,0,1,-1};
int jy[]= {1,-1,0,0};
int find(int a,char b) //看看是否已经有着把钥匙
{
int p,l,i;
if(b>='a')
p=b-'a'+1;
else
p=b-'A'+1;
for(i=0; i<p; i++)
{
l=a%2;
a/=2;
}
return l;
}
int get(int a,char b) //如果没有就拿着把钥匙 如果有就不要了否则用2进制储存会乱的
{
int p,l=1;
int i;
p=b-'a';
for(i=0; i<p; i++)
{
l*=2;
}
return (l+a);
}
int bfs(int i,int j) //bfs搜索就行 顺便进行钥匙的状态判断
{
int qian=1,hou=0;
int k;
q[0].x=i;
q[0].y=j;
q[0].z=0;
a[i][j][0]=1;
while(qian>hou)
{
t=q[hou++];
if(map[t.x][t.y]=='^'&&t.step<t1)
{
printf("%d\n",t.step);
return 0;
}
for(k=0; k<4; k++)
{
f.x=t.x+jx[k];
f.y=t.y+jy[k];
f.z=t.z;
if(f.x>=0&&f.x<n&&f.y>=0&&f.y<m&&a[f.x][f.y][f.z]==0)
{
if(map[f.x][f.y]=='^'||map[f.x][f.y]=='.'||map[f.x][f.y]=='@')
{
f.step=t.step+1;
q[qian++]=f;
a[f.x][f.y][f.z]=1;
}
else if(map[f.x][f.y]>='a'&&map[f.x][f.y]<='j')
{
f.step=t.step+1;
if(find(f.z,map[f.x][f.y])==0)
f.z=get(f.z,map[f.x][f.y]);
a[f.x][f.y][f.z]=1;
q[qian++]=f;
}
else if(map[f.x][f.y]>='A'&&map[f.x][f.y]<='J'&&find(f.z,map[f.x][f.y])==1)
{
f.step=t.step+1;
q[qian++]=f;
a[f.x][f.y][f.z]=1;
}
}
}
}
printf("-1\n");
return 0;
}
int main()
{
int i,j;
while(scanf("%d %d %d",&n,&m,&t1)!=EOF)
{
for(i=0; i<n; i++)
{
scanf("%*c%s",map[i]);
}
for(i=0; i<n; i++)
for(j=0; j<m; j++)
if(map[i][j]=='@')
{
bfs(i,j);
break;
}
}
}
从寒假开始一直想做,放着放着就忘了,前几天做poj1753看到别人的题解突然看到有用2进制的然后想到这道题目
//终于解决了这道题目