hdu 1732 推箱子 三个箱子
#include <iostream>
#include <queue>
using namespace std;
struct Point
{
int x, y;
};
struct Node
{
Point you, box[3];
int step;
};
int n, m;
char map[8][8];
Node first, next;
bool hash[8][8][8][8][8][8][8][8];
int dir[4][2] = {{1,0},{-1,0},{0,1},{0,-1}};
void setHash(Node a)
{
hash[a.you.x][a.you.y][a.box[0].x][a.box[0].y][a.box[1].x][a.box[1].y][a.box[2].x][a.box[2].y] = true;
}
bool getHash(Node a)
{
return hash[a.you.x][a.you.y][a.box[0].x][a.box[0].y][a.box[1].x][a.box[1].y][a.box[2].x][a.box[2].y];
}
bool checkPoint(Point a)
{
if (a.x >= 0 && a.x < n && a.y >= 0 && a.y < m && map[a.x][a.y] != '#')
{
return true;
}
return false;
}
//下一步是否是箱子
int isBox(Point a)
{
for (int i = 0; i < 3; ++i)
{
if (first.box[i].x == a.x && first.box[i].y == a.y)
{
return i;
}
}
return -1;
}
//箱子是否可推
bool isCanMove(Point a, int b, int di)
{
Point c;
c.x = a.x + dir[di][0];
c.y = a.y + dir[di][1];
if (!checkPoint(c))
{
return false;
}
for (int i = 0; i < 3; ++i)
{
if (i == b)
{
continue;
}
else if (first.box[i].x == c.x && first.box[i].y == c.y)
{
return false;
}
}
return true;
}
//判断是否结束
bool isEnd(Node a)
{
if (map[a.box[0].x][a.box[0].y] == '@' &&
map[a.box[1].x][a.box[1].y] == '@' &&
map[a.box[2].x][a.box[2].y] == '@')
{
return true;
}
return false;
}
//输入及初始化
void init()
{
memset(hash, 0, sizeof(hash));
int i, j, k = 0;
for (i = 0; i < n; ++i)
{
getchar();
for (j = 0; j < m; ++j)
{
scanf("%c", &map[i][j]);
if (map[i][j] == 'X')
{
first.you.x = i;
first.you.y = j;
}
else if (map[i][j] == '*')
{
first.box[k].x = i;
first.box[k++].y = j;
}
}
}
first.step = 0;
setHash(first);
}
int bfs()
{
queue <Node> Q;
Q.push(first);
while (!Q.empty())
{
first = Q.front();
Q.pop();
if (isEnd(first))
{
return first.step;
}
for (int i = 0; i < 4; ++i)
{
next = first;
next.you.x = first.you.x + dir[i][0];
next.you.y = first.you.y + dir[i][1];
next.step = first.step + 1;
if (checkPoint(next.you))
{
int k = isBox(next.you);
if (k != -1)
{
if (isCanMove(next.you, k, i))
{
next.box[k].x += dir[i][0];
next.box[k].y += dir[i][1];
if (!getHash(next))
{
setHash(next);
Q.push(next);
}
}
}
else
{
if (!getHash(next))
{
setHash(next);
Q.push(next);
}
}
}
}
}
return -1;
}
int main()
{
while (scanf("%d %d", &n, &m) != EOF)
{
init();
printf("%d\n", bfs());
}
return 0;
}
#include <queue>
using namespace std;
struct Point
{
int x, y;
};
struct Node
{
Point you, box[3];
int step;
};
int n, m;
char map[8][8];
Node first, next;
bool hash[8][8][8][8][8][8][8][8];
int dir[4][2] = {{1,0},{-1,0},{0,1},{0,-1}};
void setHash(Node a)
{
hash[a.you.x][a.you.y][a.box[0].x][a.box[0].y][a.box[1].x][a.box[1].y][a.box[2].x][a.box[2].y] = true;
}
bool getHash(Node a)
{
return hash[a.you.x][a.you.y][a.box[0].x][a.box[0].y][a.box[1].x][a.box[1].y][a.box[2].x][a.box[2].y];
}
bool checkPoint(Point a)
{
if (a.x >= 0 && a.x < n && a.y >= 0 && a.y < m && map[a.x][a.y] != '#')
{
return true;
}
return false;
}
//下一步是否是箱子
int isBox(Point a)
{
for (int i = 0; i < 3; ++i)
{
if (first.box[i].x == a.x && first.box[i].y == a.y)
{
return i;
}
}
return -1;
}
//箱子是否可推
bool isCanMove(Point a, int b, int di)
{
Point c;
c.x = a.x + dir[di][0];
c.y = a.y + dir[di][1];
if (!checkPoint(c))
{
return false;
}
for (int i = 0; i < 3; ++i)
{
if (i == b)
{
continue;
}
else if (first.box[i].x == c.x && first.box[i].y == c.y)
{
return false;
}
}
return true;
}
//判断是否结束
bool isEnd(Node a)
{
if (map[a.box[0].x][a.box[0].y] == '@' &&
map[a.box[1].x][a.box[1].y] == '@' &&
map[a.box[2].x][a.box[2].y] == '@')
{
return true;
}
return false;
}
//输入及初始化
void init()
{
memset(hash, 0, sizeof(hash));
int i, j, k = 0;
for (i = 0; i < n; ++i)
{
getchar();
for (j = 0; j < m; ++j)
{
scanf("%c", &map[i][j]);
if (map[i][j] == 'X')
{
first.you.x = i;
first.you.y = j;
}
else if (map[i][j] == '*')
{
first.box[k].x = i;
first.box[k++].y = j;
}
}
}
first.step = 0;
setHash(first);
}
int bfs()
{
queue <Node> Q;
Q.push(first);
while (!Q.empty())
{
first = Q.front();
Q.pop();
if (isEnd(first))
{
return first.step;
}
for (int i = 0; i < 4; ++i)
{
next = first;
next.you.x = first.you.x + dir[i][0];
next.you.y = first.you.y + dir[i][1];
next.step = first.step + 1;
if (checkPoint(next.you))
{
int k = isBox(next.you);
if (k != -1)
{
if (isCanMove(next.you, k, i))
{
next.box[k].x += dir[i][0];
next.box[k].y += dir[i][1];
if (!getHash(next))
{
setHash(next);
Q.push(next);
}
}
}
else
{
if (!getHash(next))
{
setHash(next);
Q.push(next);
}
}
}
}
}
return -1;
}
int main()
{
while (scanf("%d %d", &n, &m) != EOF)
{
init();
printf("%d\n", bfs());
}
return 0;
}