题目链接:POJ 1324 Pots
思路挺清晰的,就是写起来好麻烦,主要难点就是打印路径吧,可以在结构体里加一个pre表示前一个状态在vector中的下标,初始状态的pre是-1。
#include <iostream> #include <cstring> #include <cstdio> #include <queue> #include <vector> #include <stack> using namespace std; const int MAX_N = 100 + 10; const int INF = (1 << 29); int vis[MAX_N][MAX_N], arr[3]; int res; struct State { int A, B, op, dis, pre, from, to, now; State(int A = 0, int B = 0, int now = 0, int op = 0, int dis = 0, int pre = -1, int from = 0, int to = 0) : A(A), B(B), now(now), op(op), dis(dis), pre(pre), from(from), to(to) {}; }; queue <State> Q; vector <State> V; stack <int> S; void BFS() { State a; int dA, dB, pre; while(!Q.empty()) { a = Q.front(); Q.pop(); pre = a.now; // fill 1; dA = arr[0], dB = a.B; if(!vis[dA][dB]) { V.push_back(State(dA, dB, 0, 0, a.dis + 1, pre, 1)); Q.push(State(dA, dB, V.size() - 1, 0, a.dis + 1, pre)); vis[dA][dB] = 1; if(dA == arr[2] || dB == arr[2]) { res = a.dis + 1; return ; } } // fill 2; dA = a.A, dB = arr[1]; if(!vis[dA][dB]) { V.push_back(State(dA, dB, 0, 0, a.dis + 1, pre, 2)); Q.push(State(dA, dB, V.size() - 1, 0, a.dis + 1, pre)); vis[dA][dB] = 1; if(dA == arr[2] || dB == arr[2]) { res = a.dis + 1; return ; } } // pour 1 -> 2 if(a.A + a.B <= arr[1]) { dA = 0, dB = a.A + a.B; if(!vis[dA][dB]) { V.push_back(State(dA, dB, 0 , 1, a.dis + 1, pre, 1, 2)); Q.push(State(dA, dB, V.size() - 1, 1, a.dis + 1, pre)); vis[dA][dB] = 1; if(dA == arr[2] || dB == arr[2]) { res = a.dis + 1; return ; } } } else { dA = a.A - (arr[1] - a.B), dB = arr[1]; if(!vis[dA][dB]) { V.push_back(State(dA, dB, 0 , 1, a.dis + 1, pre, 1, 2)); Q.push(State(dA, dB, V.size() - 1, 1, a.dis + 1, pre)); vis[dA][dB] = 1; if(dA == arr[2] || dB == arr[2]) { res = a.dis + 1; return ; } } } // pour 2 -> 1 if(a.A + a.B <= arr[0]) { dA = a.A + a.B, dB = 0; if(!vis[dA][dB]) { V.push_back(State(dA, dB, 0 , 1, a.dis + 1, pre, 2, 1)); Q.push(State(dA, dB, V.size() - 1, 1, a.dis + 1, pre)); vis[dA][dB] = 1; if(dA == arr[2] || dB == arr[2]) { res = a.dis + 1; return ; } } } else { dA = arr[0], dB = a.B - (arr[0] - a.A); if(!vis[dA][dB]) { V.push_back(State(dA, dB, 0 , 1, a.dis + 1, pre, 2, 1)); Q.push(State(dA, dB, V.size() - 1, 1, a.dis + 1, pre)); vis[dA][dB] = 1; if(dA == arr[2] || dB == arr[2]) { res = a.dis + 1; return ; } } } // drop 1 dA = 0, dB = a.B; if(!vis[dA][dB]) { V.push_back(State(dA, dB, 0 , 2, a.dis + 1, pre, 1)); Q.push(State(dA, dB, V.size() - 1, 2, a.dis + 1, pre)); vis[dA][dB] = 1; if(dA == arr[2] || dB == arr[2]) { res = a.dis + 1; return ; } } // drop 2 dA = a.A, dB = 0; if(!vis[dA][dB]) { V.push_back(State(dA, dB, 0 , 2, a.dis + 1, pre, 2)); Q.push(State(dA, dB, V.size() - 1, 2, a.dis + 1, pre)); vis[dA][dB] = 1; if(dA == arr[2] || dB == arr[2]) { res = a.dis + 1; return ; } } } } void print() { printf("%d\n", res); int i = V.size() - 1; while(V[i].pre != -1) { S.push(i); i = V[i].pre; } while(!S.empty()) { if(V[S.top()].op == 0) printf("FILL(%d)\n", S.top(), V[S.top()].from); else if(V[S.top()].op == 1) printf("POUR(%d,%d)\n", V[S.top()].from, V[S.top()].to); else if(V[S.top()].op == 2) printf("DROP(%d)\n", V[S.top()].from); S.pop(); } } int main() { //freopen("in.txt", "r", stdin); res = INF; memset(vis, 0, sizeof(vis)); scanf("%d%d%d", &arr[0], &arr[1], &arr[2]); vis[0][0] = 1; V.push_back(State(0, 0)); Q.push(State(0, 0, V.size() - 1)); BFS(); if(res == INF) printf("impossible\n"); else print(); return 0; }