原网站:http://acm.hdu.edu.cn/showproblem.php?pid=1429
题目中文的,意思在不懂,我只能说:"苟。。。"
好了,不扯没用的了,直接贴代码吧。
代码乍一看很有意思,因为用二进制的方法来记录钥匙与门的匹配,不太常见,其实是典型的状态压缩的题目,可以一试。
其实就是紫书上现学现卖的。。。。。。。。。。。
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
int dx[] = { 1,-1,0,0 };
int dy[] = { 0,0,-1,1 };
char dzm[] = { 'A','B','C','D','E','F','G','H','I','J' };
char xzm[] = { 'a','b','c','d','e','f','g','h','i','j' };
struct point {
int x, y;
int step, dir;
};
int n, m, sx, sy;
int visit[30][30][1050];//记录钥匙
char map[30][30];
int bfs()
{
int i, j;
memset(visit, 0, sizeof(visit));
queue<point>Q;
point now, next;
now.x = sx; now.y = sy;
now.step = now.dir = 0;
visit[now.x][now.y][now.dir] = 1;
Q.push(now);
while (!Q.empty())
{
now = Q.front();
Q.pop();
if (map[now.x][now.y] == '^')
return now.step;
for (i = 0; i<4; i++)
{
next.x = now.x + dx[i];
next.y = now.y + dy[i];
next.step = now.step + 1;
next.dir = now.dir;
if (map[next.x][next.y] == '*')continue;
if (next.x<1 || next.x>n || next.y<1 || next.y>m)continue;
if (map[next.x][next.y] <= 'J'&&map[next.x][next.y] >= 'A')
{
for (j = 0; j<10; j++)
{
if (map[next.x][next.y] == dzm[j])
{
if ((next.dir&(1 << j)) != 0)
{
if (visit[next.x][next.y][next.dir] == 0)
{
visit[next.x][next.y][next.dir] = 1;
Q.push(next);
}
}
}
}
}
else if (map[next.x][next.y] <= 'j'&&map[next.x][next.y] >= 'a')
{
for (j = 0; j<10; j++)
{
if (map[next.x][next.y] == xzm[j])
{
if ((next.dir&(1 << j)) == 0)
next.dir += (1 << j);
if (visit[next.x][next.y][next.dir] == 0)
{
visit[next.x][next.y][next.dir] = 1;
Q.push(next);
}
}
}
}
else
{
if (visit[next.x][next.y][next.dir] == 0)
{
visit[next.x][next.y][next.dir] = 1;
Q.push(next);
}
}
}
}
return -1;
}
int main()
{
int i, j, t;
while (scanf("%d %d %d", &n, &m, &t)!=EOF)
{
getchar();
for (i = 1; i <= n; i++)
{
for (j = 1; j <= m; j++)
{
scanf(" %c", &map[i][j]);
if (map[i][j] == '@')
sx = i, sy = j;
}
}
int q = bfs();
if (q >= t)
printf("-1\n");
else
printf("%d\n", q);
}
return 0;
}