POJ-3414 Pots BFS+记忆路径

这题让我想起了杭电的那一道三个可乐罐的题目,那一题好像只要输出次数就可以了,而这里则需要将所有的路径全部输出出来,这样的话,单纯的BFS则会在状态的保留上会出现大量的空间冗余。于是这题在考虑到搜索空间一定的情况下,并且这些空间具有只访问一次的特性,因此,可以直接对题目进行构图,也就是相当于BFS中不对队列进行删除元素。通过一个二维数组来存储传递路径,再通过一个二维数组来存储父亲结点。

代码如下:

#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <queue>
#include <algorithm>
using namespace std;

// 直接用G[i][j]来进行构图,P[i][j]记录父亲 

int x, y, z, G[105][105], P[105][105], endx, endy;

struct Node {
    int x, y, ti;
}info, pos;

queue<Node>q;

char ss[10][15] = {
"", "FILL(1)", "FILL(2)", "DROP(1)",
"DROP(2)", "POUR(1,2)", "POUR(2,1)",
};
/*
定义: 
1.FILL(1)
2.FILL(2)
3.DROP(1)
4.DROP(2)
5.POUR(1,2)
6.POUR(2,1)
一共六种操作
*/ 

bool push(int op) {
    if (!G[info.x][info.y]) {
        q.push(info);
        G[info.x][info.y] = op;
        P[info.x][info.y] = pos.x * 1000 + pos.y;
        if (info.x == z || info.y == z) {
            endx = info.x, endy = info.y;
            return true;
        }
    }
    return false;
}

int bfs(int &step) {
    while (!q.empty()) q.pop();
    bool finish = false;
    info.x = 0, info.y = 0, info.ti = 0;
    G[info.x][info.y] = -1;
    q.push(info);
    while (!q.empty()) {
        pos = q.front();
        q.pop();
        info.ti = pos.ti + 1;
        info.x = x, info.y = pos.y;
        finish |= push(1); 
        info.x = pos.x, info.y = y;
        finish |= push(2);
        info.x = 0, info.y = pos.y;
        finish |= push(3);
        info.x = pos.x, info.y = 0;
        finish |= push(4);
        info.x = pos.x - min(pos.x, y - pos.y);
        info.y = pos.y + pos.x - info.x;
        finish |= push(5);
        info.y = pos.y - min(pos.y, x - pos.x);
        info.x = pos.x + pos.y - info.y;
        finish |= push(6);
        if (finish) {
            step = info.ti;
            break;
        }
    }
    return finish;
}

void dfs(int a, int b) {
    if (a || b) {
        dfs(P[a][b]/1000, P[a][b]%1000);
        puts(ss[G[a][b]]);
    }
}

void display(int &step) {
    int a = endx, b = endy;
    printf("%d\n", step);
    dfs(a, b);
}

int main() {
    int step;
    while (scanf("%d %d %d", &x, &y, &z) == 3) {
        memset(G, 0, sizeof (G));
        if (bfs(step)) {
            display(step);
        } else {
            puts("impossible");
        }
    }
    return 0;
}
posted @ 2012-11-16 21:53  沐阳  阅读(537)  评论(0编辑  收藏  举报