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;
}

posted on 2009-05-16 20:52  ZAFU_VA  阅读(320)  评论(0)    收藏  举报

导航