题目链接: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;
}
本文提供了一种解决POJ1324Pots问题的有效方法,通过广度优先搜索(BFS)算法寻找从初始状态到目标状态的最短路径,并详细记录了实现过程及路径打印方案。
748

被折叠的 条评论
为什么被折叠?



