与其他bfs不同的是这种题需要用二进制来保存钥匙这个状态,需要多用一维数组来保存。。
可以通过位运算 | “拾取钥匙”, & “匹配钥匙”。
#include "string"
#include "iostream"
#include "cstdio"
#include "cmath"
#include "set"
#include "queue"
#include "vector"
#include "cctype"
#include "sstream"
#include "cstdlib"
#include "cstring"
#include "stack"
//#include "ctime"
#include "algorithm"
#define pa pair<int,int>
#define Pi M_PI
#define INF 0x3f3f3f3f
#define INFL 0x3f3f3f3f3f3f3f3fLL
using namespace std;
typedef long long LL;
const int M=55;
struct Node
{
int x, y;
int kind;
int t;
} star;
int n, m, time;
int dis[4][2] = {1, 0, 0, -1, -1, 0, 0, 1};
char map[21][21];
bool mark[20][20][1100];
int BFS()
{
int i, j, kind, temp, t;
struct Node node, next;
queue<Node> Q;
star.kind = 0;
star.t = 0;
Q.push(star);
mark[star.x][star.y][0] = true;
while(!Q.empty())
{
node = Q.front();
Q.pop();
kind = node.kind;
t = node.t;
if( t % time == 0 && t != 0)
{
node.x = star.x;
node.y = star.y;
}
if( map[node.x][node.y] == '^')
return node.t;
for( i = 0 ; i < 4 ; i++)
{
next.x = node.x + dis[i][0];
next.y = node.y + dis[i][1];
next.kind = kind;
if( next.x < 0 || next.y < 0 || next.x >= n || next.y >= m)
continue;
if( map[next.x][next.y] == '*' || mark[next.x][next.y][next.kind] == true)
continue;
next.t = t + 1;
if( islower(map[next.x][next.y]))
{
j = map[next.x][next.y] - 'a';
if( (kind & (1 << j) ) == 0) //存储钥匙
next.kind = kind + (1 << j);
}
else if( isupper( map[next.x][next.y]) )
{
j = map[next.x][next.y] - 'A';
temp = kind >> j;
if( (temp & 1 ) == 0) //判断钥匙能匹配不
continue;
next.kind = kind;
}
mark[next.x][next.y][next.kind] = true;
Q.push(next);
}
}
return -1;
}
int main()
{
int i, j, k, ans;
k = 0;
while(~ scanf("%d%d%d", &n, &m, &time))
{
memset( mark, 0, sizeof(mark));
for( i = 0 ; i < n ; i++)
{
for( j = 0 ; j < m ; j++)
{
cin>>map[i][j];
if( map[i][j] == '@')
{
star.x=i;
star.y=j;
}
}
}
ans = BFS();
printf("%d\n", ans);
}
}