http://acm.hdu.edu.cn/showproblem.php?pid=1429
第一次做 感觉有点困难 毕竟接触 BFS不久
两点值得学习
1,记录10把钥匙的状态 即vis[][][1024]的 作用 1024 (2^10)中状态 。。。状态 学长 屡次强调 且 屡次解释 的一个 东西
每种状态只能走一个点一次 这是和 最简单迷宫的 区别 。。
2,位运算 >> << & | 这与上面的1024相对应 ,作为新手这个的确不大熟悉 。。。。
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
struct node
{
int x,y;
int step,key;
}dui[5000000];
int s_x,s_y,e_x,e_y,t;
int n,m;
int dir[4][2]={0,1,0,-1,1,0,-1,0};
char map[25][25];
int mark[25][25][1025];
int bfs()
{
int i,j,head,tail;
int key;
struct node now,next;
head=tail=0;
dui[tail].x=s_x;
dui[tail].y=s_y;
dui[tail].step=0;
dui[tail++].key=0;
while(head<tail)
{
now.x=dui[head].x;
now.y=dui[head].y;
now.step=dui[head].step;
now.key=dui[head++].key;
for(i=0;i<4;i++)
{
next.x=now.x+dir[i][0];
next.y=now.y+dir[i][1];
next.step=now.step+1;
next.key=now.key;
if(next.x<0 || next.x>=n ||next.y<0 || next.y>=m) continue;
if(map[next.x][next.y]=='*') continue;
if(map[next.x][next.y]>='a' && map[next.x][next.y]<='j')
{
key=1<<(map[next.x][next.y]-'a');
next.key=next.key|key;
}
else if(map[next.x][next.y]>='A' && map[next.x][next.y]<='J')
{
key=1<<(map[next.x][next.y]-'A');
if( (key&next.key)==0 ) continue;
}
if(mark[next.x][next.y][next.key]) continue;
mark[next.x][next.y][next.key]=1;
if(next.x==e_x && next.y==e_y)
{
if(next.step<t) return next.step;
else return -1;
}
dui[tail].x=next.x;
dui[tail].y=next.y;
dui[tail].step=next.step;
dui[tail++].key=next.key;
}
}
return -1;
}
int main()
{
int i,j;
while(scanf("%d%d%d",&n,&m,&t)!=EOF)
{
getchar();
for(i=0;i<n;i++)
{
for(j=0;j<m;j++)
{
scanf("%c",&map[i][j]);
if(map[i][j]=='@')
{
s_x=i; s_y=j;
}
else if(map[i][j]=='^')
{
e_x=i; e_y=j;
}
}
getchar();
}
memset(mark,0,sizeof(mark));
printf("%d\n",bfs());
}
return 0;
}