题目:http://acm.hdu.edu.cn/showproblem.php?pid=1429
题意:迷宫问题, 多了门和钥匙。
第一道状态压缩, 利用二进制来保存是否得到钥匙, 三维数组Judge[][][], 记录状态, 为什么会走“回头路”, 因为在所走步数最少的情况下, 走回头路的情况只能是取钥匙再回来的时候才有, 但是取完钥匙后,虽在同一点但其状态已将变化(钥匙 有-->无)。 可以看作把钥匙加入钥匙串。
利用二进制判断钥匙是否在串中 或加入钥匙串:
判断门是否会打开时用 钥匙与门编号进行'&'----> 例如: 1000100010 & 0000100000 != 0 说明可以打开‘A’ + 6这道门。
如果碰到钥匙要加入该钥匙。将钥匙加入钥匙串要进行'|' ---->例如:1000100010 | 0000010000 = 1000110010;’e'入串。
知道了这些, 就直接可以跑Bfs了 ^~^!
#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
char map[ 21][ 21]; int ac[ 4][ 2] = { 0, 1, 0, - 1, - 1, 0, 1, 0};
bool Judge[ 21][ 21][ 1025];
int n, m, T;
struct Maze
{
int x, y, step, Key;
} r, s, t;
int Bfs( int a, int b)
{
r.x = a; r.y = b; r.step = 0; r.Key = 0;
Judge[a][b][ 0] = true;
queue<Maze> Q;
Q.push(r);
while(!Q.empty())
{
s = Q.front(); Q.pop();
// printf("%d %d\n", s.x, s.y);
for( int i = 0; i < 4; i++)
{
t.x = s.x + ac[i][ 0];
t.y = s.y + ac[i][ 1];
t.step = s.step + 1;
t.Key = s.Key;
if(t.x >= 0 && t.x < n && t.y >= 0 && t.y < m && map[t.x][t.y] != ' * ' && t.step < T && !Judge[t.x][t.y][t.Key])
{
if(map[t.x][t.y] == ' ^ ')
return t.step;
if(map[t.x][t.y] >= ' a ' && map[t.x][t.y] <= ' j ')
{
int temp = map[t.x][t.y] - ' a ';
if((t.Key & ( 1 << temp)) == 0) // 小细节, 位运算作比较用时要加括号!!!!!!
t.Key += ( 1 << temp);
}
if(map[t.x][t.y] >= ' A ' && map[t.x][t.y] <= ' J ')
{
int temp = map[t.x][t.y] - ' A ';
if((t.Key & ( 1 << temp)) == 0)
continue;
}
Judge[t.x][t.y][t.Key] = true;
Q.push(t);
}
}
}
return - 1;
}
int main()
{
while(~scanf( " %d %d %d ", &n, &m, &T))
{
int x, y;
for( int i = 0; i < n; i++)
{
scanf( " %s ", map[i]);
for( int j = 0; j < m; j++)
{
if(map[i][j] == ' @ ')
x= i, y = j, map[i][j] = ' . ';
}
}
memset(Judge, false, sizeof(Judge));
printf( " %d\n ", Bfs(x, y));
}
return 0; }
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
char map[ 21][ 21]; int ac[ 4][ 2] = { 0, 1, 0, - 1, - 1, 0, 1, 0};
bool Judge[ 21][ 21][ 1025];
int n, m, T;
struct Maze
{
int x, y, step, Key;
} r, s, t;
int Bfs( int a, int b)
{
r.x = a; r.y = b; r.step = 0; r.Key = 0;
Judge[a][b][ 0] = true;
queue<Maze> Q;
Q.push(r);
while(!Q.empty())
{
s = Q.front(); Q.pop();
// printf("%d %d\n", s.x, s.y);
for( int i = 0; i < 4; i++)
{
t.x = s.x + ac[i][ 0];
t.y = s.y + ac[i][ 1];
t.step = s.step + 1;
t.Key = s.Key;
if(t.x >= 0 && t.x < n && t.y >= 0 && t.y < m && map[t.x][t.y] != ' * ' && t.step < T && !Judge[t.x][t.y][t.Key])
{
if(map[t.x][t.y] == ' ^ ')
return t.step;
if(map[t.x][t.y] >= ' a ' && map[t.x][t.y] <= ' j ')
{
int temp = map[t.x][t.y] - ' a ';
if((t.Key & ( 1 << temp)) == 0) // 小细节, 位运算作比较用时要加括号!!!!!!
t.Key += ( 1 << temp);
}
if(map[t.x][t.y] >= ' A ' && map[t.x][t.y] <= ' J ')
{
int temp = map[t.x][t.y] - ' A ';
if((t.Key & ( 1 << temp)) == 0)
continue;
}
Judge[t.x][t.y][t.Key] = true;
Q.push(t);
}
}
}
return - 1;
}
int main()
{
while(~scanf( " %d %d %d ", &n, &m, &T))
{
int x, y;
for( int i = 0; i < n; i++)
{
scanf( " %s ", map[i]);
for( int j = 0; j < m; j++)
{
if(map[i][j] == ' @ ')
x= i, y = j, map[i][j] = ' . ';
}
}
memset(Judge, false, sizeof(Judge));
printf( " %d\n ", Bfs(x, y));
}
return 0; }