POJ 3414 Pots

题目链接:POJ 3414 Pots

题目大意:
给你两个体积分别为(A)(B)的容器,你对它们有三种操作,一种是装满其中一个瓶子,另一种是把其中一个瓶子的水都倒掉,还有一种就是把其中一个瓶子的水导入另一个瓶子中(可能会有剩余)。最后让你输出在能够得出体积为(C)的水的情况下操作的最小次数并且把过程输出。如果无法得出体积为(C)的水,则输出“impossible”。

题解:
模拟六种倒水情况并用BFS获取做小步数,用结构体中的prea、preb记录上一步的情况,并用递归输出整个过程,结构体中的step不仅记录步数,同时也起到标记的作用。

#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
#define ms(a, b) memset(a, b, sizeof(a))
#define MAXN 105

int A, B, C;
struct node {
    int a, b, prea, preb, way, step;
} path[MAXN][MAXN];
queue <node> q;

void print(int a, int b) {
    if (!path[a][b].a && !path[a][b].b)	return;
    print(path[a][b].prea, path[a][b].preb);
    switch (path[a][b].way) {
        case 1: 
        	cout << "FILL(1)" << endl;	
        	break;
        case 2: 
        	cout << "FILL(2)" << endl;	
        	break;
        case 3: 
        	cout << "DROP(1)" << endl;	
        	break;
        case 4: 
        	cout << "DROP(2)" << endl;	
        	break;
        case 5: 
        	cout << "POUR(1,2)" << endl;	
        	break;
        case 6: 
        	cout << "POUR(2,1)" << endl;	
        	break;
    }
}

void push(node t) {
    if (!path[t.a][t.b].step) {
        q.push(t);
        path[t.a][t.b] = t;
    }
}

void bfs() {
    q.push(path[0][0]);
    while (!q.empty()) {
        node u = q.front();
        q.pop();
        if (u.a == C || u.b == C) {
            cout << u.step << endl;
            print(u.a, u.b);
            return;
        }
        node v;
        v.prea = u.a;
        v.preb = u.b;
        v.step = u.step + 1;
        // 六种情况
        if (u.a != A) {
            v.a = A;
            v.b = u.b;
            v.way = 1;
            push(v);
    	}
        if (u.b != B) {
            v.b = B;
            v.a = u.a;
            v.way = 2;
            push(v);
        }
        if (u.a) {
            v.a = 0;
            v.b = u.b;
            v.way = 3;
            push(v);
        }
        if (u.b) {
            v.a = u.a;
            v.b = 0;
            v.way = 4;
            push(v);
        }
        if (u.a && u.b != B) {
            if (u.a + u.b >= B) {
                v.b = B;
                v.a = u.a + u.b - B;
            } else {
                v.a = 0;
                v.b = u.a + u.b;
            }
            v.way = 5;
            push(v);
        }
        if (u.a != A && u.b) {
            if (u.a + u.b >= A) {
                v.a = A;
                v.b = u.a + u.b - A;
            } else {
                v.a = u.a + u.b;
                v.b = 0;
            }
            v.way = 6;
            push(v);
        }
    }
    cout << "impossible" << endl;
}

int main() {
    ms(path, 0);
    path[0][0].a = path[0][0].b = 0;
    path[0][0].prea = path[0][0].preb = -1;
    path[0][0].step = 0;
    cin >> A >> B >> C;
    bfs();
    return 0;
}
原文地址:https://www.cnblogs.com/IzumiSagiri/p/13765408.html