pku 1475 推箱子
#include <iostream>
#include <queue>
#include <string>
using namespace std;
const int MAXSIZE = 21;
int dir[4][2] = {{-1, 0},{1, 0},{0, -1},{0, 1}};}};//将这里改了下就ac了... 显然是有多种情况的sj的吧= =
char you_rute[] = "nswe";
char box_rute[] = "NSWE";
class Point
{
public:
int x, y;
};
class YouPoint
{
public:
Point you;
int step;
string yourute;
};
class State
{
public:
Point box, you;
int step;
string staterute;
};
class PushBox
{
public:
PushBox(int, int);
bool bfs();
bool order_bfs(Point, Point);
private:
char map[MAXSIZE][MAXSIZE];
int width, height;
Point box, you, target;
int hash[MAXSIZE][MAXSIZE];
int fuck[MAXSIZE][MAXSIZE][MAXSIZE][MAXSIZE];
YouPoint you_first, you_next;
State first, next;
};
PushBox::PushBox(int n, int m) : width(n), height(m)
{
int i, j;
for (i = 0; i < n; ++i)
{
getchar();
for (j = 0; j < m; ++j)
{
scanf("%c", &map[i][j]);
if (map[i][j] == 'T')
{
target.x = i;
target.y = j;
map[i][j] = '.';
}
else if (map[i][j] == 'B')
{
box.x = i;
box.y = j;
map[i][j] = '.';
}
else if (map[i][j] == 'S')
{
you.x = i;
you.y = j;
map[i][j] = '.';
}
}
}
bool flag = bfs();
if (flag)
{
cout << first.staterute << endl;
}
else
{
cout << "Impossible." << endl;
}
}
bool PushBox::bfs()
{
queue <State> Q;
memset(fuck, 4, sizeof (fuck));
first.box.x = box.x;
first.box.y = box.y;
first.you.x = you.x;
first.you.y = you.y;
first.step = 0;
first.staterute = "";
fuck[first.you.x][first.you.y][first.box.x][first.box.y] = 0;
Q.push(first);
while (!Q.empty())
{
first = Q.front();
Q.pop();
if (first.box.x == target.x && first.box.y == target.y)
{
return true;
}
int i;
for (i = 0; i < 4; ++i)
{
next.box.x = first.box.x + dir[i][0];
next.box.y = first.box.y + dir[i][1];
next.you.x = first.box.x - dir[i][0];
next.you.y = first.box.y - dir[i][1];
if (next.box.x >= 0 && next.box.x < width && next.box.y >= 0 && next.box.y < height
&& next.you.x >= 0 && next.you.x < width && next.you.y >= 0 && next.you.y < height
&& map[next.box.x][next.box.y] == '.' && map[next.you.x][next.you.y] == '.')
{
if (order_bfs(first.you, next.you))
{
next.step = first.step + 1;
next.you = first.box;
if (next.step < fuck[next.you.x][next.you.y][next.box.x][next.box.y])
{
fuck[next.you.x][next.you.y][next.box.x][next.box.y] = next.step;
next.staterute = first.staterute + you_first.yourute + box_rute[i];
Q.push(next);
}
}
}
}
}
return false;
}
bool PushBox::order_bfs(Point start, Point end)
{
queue <YouPoint> Q;
memset(hash, 4, sizeof (hash));
you_first.you = start;
you_first.step = 0;
you_first.yourute = "";
hash[you_first.you.x][you_first.you.y] = 0;
Q.push(you_first);
while (!Q.empty())
{
you_first = Q.front();
Q.pop();
if (you_first.you.x == end.x && you_first.you.y == end.y)
{
return true;
}
int i;
for (i = 0; i < 4; ++i)
{
you_next.you.x = you_first.you.x + dir[i][0];
you_next.you.y = you_first.you.y + dir[i][1];
if (you_next.you.x >= 0 && you_next.you.x < width && you_next.you.y >= 0 &&
you_next.you.y < height && map[you_next.you.x][you_next.you.y] == '.')
{
if (you_next.you.x == first.box.x && you_next.you.y == first.box.y) // 不能走在原先有box的地方
{
continue;
}
you_next.step = you_first.step + 1;
if (you_next.step < hash[you_next.you.x][you_next.you.y])
{
hash[you_next.you.x][you_next.you.y] = you_next.step;
you_next.yourute = you_first.yourute + you_rute[i];
Q.push(you_next);
}
}
}
}
return false;
}
int main()
{
int n, m, cnt = 0;
while (scanf("%d %d", &n, &m) != EOF)
{
if (n == 0 && m == 0)
{
break;
}
printf("Maze #%d\n", ++cnt);
PushBox pb(n, m);
printf("\n");
}
return 0;
}
浙公网安备 33010602011771号