要明白状态是什么 : 每一个状态就是每一时刻两个杯子中水的数量。 (k1, k2)
至于记录路径这里我使用的指针,自然不用指针,把每一个状态标号也是一样。
不知为什么,这个题目引用 STL 中的 queue 就 RuntimeError, 难道是指针和队列内队列外的缘故。
// 2012-06-03 Author : a_clay
// poj 3414 pots -- 最爱的 BFS
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#include <stack>
#include <memory.h>
#include <cstdio>
using namespace std;
const int N = 101;
struct node {
int k1, k2, steps;
int op;
node *pre;
}que[N*N];
node cur, nex;
int vis[N][N];
char str[][10] = {"FILL(1)", "DROP(1)", "FILL(2)", "DROP(2)", "POUR(1,2)", "POUR(2,1)"};
void DFS(node* t) {
if(t->pre != NULL) {
DFS(t->pre);
cout << str[t->op] << endl;
}
}
void BFS(int v1, int v2, int c) {
que[0] = cur;
vis[0][0] = 1; int yi;
int head = 0, tail = 1;
node* cp;
while(head < tail) {
cp = &que[head++];
if(cp->k1 == c || cp->k2 == c) {
//Bug;
printf("%d\n", cp->steps);
DFS(cp);
return;
}
for(int i = 0; i < 6; i++) {
switch(i) {
case 0 : nex.k1 = v1; nex.k2 = cp->k2; break; // A 满
case 1 : nex.k1 = 0; nex.k2 = cp->k2; break; // A 空
case 2 : nex.k1 = cp->k1; nex.k2 = v2; break; // B 满
case 3 : nex.k1 = cp->k1; nex.k2 = 0; break; // B 空
case 4 : yi = cp->k1 + cp->k2 - v2; // A -> B
if(yi > 0) {
nex.k1 = yi;
nex.k2 = v2;
}
else {
nex.k1 = 0;
nex.k2 = yi+v2;
}
break;
case 5 : yi = cp->k1 + cp->k2 - v1; // B -> A
if(yi > 0) {
nex.k1 = v1;
nex.k2 = yi;
}
else {
nex.k1 = yi+v1;
nex.k2 = 0;
}
}
nex.steps = cp->steps + 1;
nex.pre = cp;
nex.op = i;
if(!vis[nex.k1][nex.k2]) {
que[tail++] = nex;
vis[nex.k2][nex.k2] = 1;
}
}
}
cout << "impossible" << endl;
}
int main() {
int v1, v2, c;
while(scanf("%d%d%d", &v1, &v2, &c) == 3) {
memset(vis, 0, sizeof(vis));
BFS(v1, v2, c);
}
return 0;
}
本文介绍了一种使用广度优先搜索(BFS)算法解决经典的倒水问题的方法。通过定义状态为两个水壶中水的体积,并利用结构体存储当前状态、步骤数及前驱状态等信息,实现了从初始状态到目标状态的路径查找。代码中详细展示了如何通过switch-case结构模拟倒水操作,并通过递归函数输出最优解决方案。
697

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



