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;

}

你可能感兴趣的:(poj)