题目描述
话说
CZ
由于不守基道,被妖怪抓走了,好基友
WP
在努力讨好高富帅
RQ
救出
CZ
的同时,
CZ
也意识到了自己的错误,然后努力的想逃出妖怪的闺房。
妖怪的闺房是一个n*m的矩阵,并且某些地方安装了带锁的门,钥匙藏在闺房另外的某些地方。刚开始WP被关在(sx,sy)的位置,离开闺房的门在(ex,ey)的位置。WP每分钟只能从一个坐标走到相邻四个坐标中的其中一个。妖怪每t分钟回闺房视察一次,若发现CZ不在原位置便把他再拎回去。经过若干次的尝试,CZ已画出整个闺房的地图。现在请你帮他计算能否再次成功逃亡。只要在妖怪下次视察之前走到出口就算离开闺房,如果妖怪回来的时候刚好走到出口或还未到出口都算逃亡失败。
输入
每组测试数据的第一行有三个整数
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
每组测试数据之间有一个空行。
输出
针对每组测试数据,如果可以成功逃亡,请输出最少需要多少分钟才能离开,如果不能则输出
-1。
示例输入
4 5 17 @A.B. a*.*. *..*^ c..b* 4 5 16 @A.B. a*.*. *..*^ c..b*
示例输出
16 -1
本题的难点是在于钥匙的状态。上网查阅一番才知道用2进制的表示方法,顿时茅塞顿开,同时感觉智商已被深深压制。故在此解释一下2进制的用法。
本题钥匙用a~j表示,门用A~J表示则将其表示为2进制只需对相应字符减一个‘a’或‘A’,再以此循环乘2。把结果加到储存状态的变量上,这样虽然是一个数,但它写成2进制是就可以变成0000000,1111111这样的数。如果第一位是0,则表示没有钥匙a,如果是一则拥有a,同理第二位表示b。。。。这样做高明就高明在用一个数就能表示多种状态,是在佩服那些大神的智慧啊。
本题代码如下:
#include <stdio.h> #include <stdlib.h> #include <string.h> struct B { int x,y,z; int step; } p[1000001],q,f; char map[22][22]; int vis[22][22][1101]; int mov[4][2]= {{1,0},{-1,0},{0,1},{0,-1}}; int n,m,t; void bfs(int x,int y) { int top=0,low=0; int i,flag=0; q.x=x; q.y=y; q.z=0; q.step=0; vis[q.x][q.y][0]=1; p[top++]=q; while(low<top) { q=p[low++]; if(map[q.x][q.y]=='^') { if(q.step<t){printf("%d\n",q.step);flag=1;} break; } for(i=0; i<4; i++) { f.x=q.x+mov[i][0]; f.y=q.y+mov[i][1]; f.z=q.z; if(0<=f.x&&f.x<n&&0<=f.y&&f.y<m&& vis[f.x][f.y][f.z]==0&&map[f.x][f.y]!='*') { if(map[f.x][f.y]=='^'||map[f.x][f.y]=='.'|| map[f.x][f.y]=='@') { f.step=q.step+1; p[top++]=f; vis[f.x][f.y][f.z]=1; } else { if('a'<=map[f.x][f.y]&&map[f.x][f.y]<='j') { int ll=map[f.x][f.y]-'a',kk=f.z,sum;\\储存钥匙状态 while(ll--) { kk=kk/2; } sum=kk%2; if(sum==0) { ll=map[f.x][f.y]-'a'; kk=1; while(ll--) { kk=kk*2; } f.z=f.z+kk; } f.step=q.step+1; p[top++]=f; vis[f.x][f.y][f.z]=1; } else { if(map[f.x][f.y]>='A'&&map[f.x][f.y]<='J')\\判断钥匙是否存在 { int ll=map[f.x][f.y]-'A',kk=f.z,sum; while(ll--) { kk=kk/2; } sum=kk%2; if(sum==1) { f.step=q.step+1; p[top++]=f; vis[f.x][f.y][f.z]=1; } } } } } } } if(flag==0) printf("-1\n"); return ; } int main() { int i,j; while(scanf("%d %d %d",&n,&m,&t)!=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]=='@')break; } if(j!=m)break; } memset(vis,0,sizeof(vis)); bfs(i,j); } return 0; }