題目描述
話說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;
}