做了一些关于BFS的题目,每个题目的描述不一样,但是特点都是移动时状态的改变。这道题主要就是找到最短路径上的锁的钥匙,解锁并出逃。当前是否拥有特定锁的钥匙的状态可以用二进制压缩的方法记录。初次接触状态压缩,对它的原理还有待进一步的了解,现在只是模仿大神的方法试敲。
ps:这道题之前一直CE,原因是命名空间中的next关键字和我自己定义的变量冲突,浪费了不少时间,下次切记避免这种问题。
http://acm.hdu.edu.cn/showproblem.php?pid=1429
#include<cstdio>
#include<cstring>
#include<queue>
#define MAX 21
using namespace std;
char maze[MAX][MAX];
bool flag[MAX][MAX][1024];
int dir[4][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
int n, m, t;
struct P{
short x, y, step, key;
bool legal(){
if(x >= 0 && x < n && y >= 0 && y < m)
return true;
return false;
}
}s, next1;
int bfs(){
memset(flag, false, sizeof(flag));
queue<P> que;
que.push(s);
while(!que.empty()){
P p = que.front();
que.pop();
for(int i = 0;i < 4;i++){
next1 = p;
next1.x = p.x + dir[i][0];
next1.y = p.y + dir[i][1];
next1.step++;
if(next1.step >= t)
break;
if(next1.legal() && maze[next1.x][next1.y] != '*'){
if(maze[next1.x][next1.y] == '^')
return next1.step;
if(maze[next1.x][next1.y] >= 'A' && maze[next1.x][next1.y] <= 'J'){
if((1<<(maze[next1.x][next1.y] - 'A'))&next1.key && flag[next1.x][next1.y][next1.key] == false){
que.push(next1);
flag[next1.x][next1.y][next1.key] = true;
}
}
else if(maze[next1.x][next1.y] >= 'a' && maze[next1.x][next1.y] <= 'j'){
next1.key |= (1<<(maze[next1.x][next1.y] - 'a'));
if(flag[next1.x][next1.y][next1.key] == false){
que.push(next1);
flag[next1.x][next1.y][next1.key] = true;
}
}
else{
if(!flag[next1.x][next1.y][next1.key]){
que.push(next1);
flag[next1.x][next1.y][next1.key] = true;
}
}
}
}
}
return -1;
}
main(){
while(~scanf("%d %d %d", &n, &m, &t)){
getchar();
for(int i = 0;i < n;i++){
gets(maze[i]);
}
for(int i = 0;i < n;i++){
for(int j = 0;j < m;j++){
if(maze[i][j] == '@'){
s.x = i;
s.y = j;
s.key = 0;
s.step = 0;
}
}
}
int res = bfs();
printf("%d\n",res);
}
}