【正经题解】倒水问题
2024-03-15 17:51:37
发布于:浙江
90阅读
0回复
0点赞
使用宽度优先搜索( )来搜索所有可能的状态。
定义状态结构体( ),其中 和 分别表示两个水桶中的水量, 表示当前操作步数, 表示操作的字符串序 列。
从初始状态开始,进行如下操作:
:将第 个水桶装满, 为 或 。
:将第 个水桶清空, 为 或 。
:将第 个水桶的水全部倒入 桶, 空了或 满了停止, , 为 或 。
对于每个操作,更新水桶的状态,将新的状态加入队列。
如果搜索过程中找到了满足目标状态的解,输出最少操作次数和操作过程。否则,输出 。
#include<bits/stdc++.h>
using namespace std;
int n, m, k;
int vis[105][105];
// 定义结构体表示状态
struct Node {
int a, b, step;
string s;
};
// 宽度优先搜索
void bfs() {
queue<Node> q;
q.push({0, 0, 0, ""});
while (!q.empty()) {
Node f = q.front();
q.pop();
// 判断是否达到目标状态
if (f.a == k || f.b == k) {
cout << f.step << endl; // 输出最少操作次数
cout << f.s << endl; // 输出操作过程
return;
}
// FILL操作
if (!vis[n][f.b]) {
vis[n][f.b] = 1;
q.push({n, f.b, f.step + 1, f.s + "FILL(1)\n"});
}
if (!vis[f.a][m]) {
vis[f.a][m] = 1;
q.push({f.a, m, f.step + 1, f.s + "FILL(2)\n"});
}
// DROP操作
if (!vis[0][f.b]) {
vis[0][f.b] = 1;
q.push({0, f.b, f.step + 1, f.s + "DROP(1)\n"});
}
if (!vis[f.a][0]) {
vis[f.a][0] = 1;
q.push({f.a, 0, f.step + 1, f.s + "DROP(2)\n"});
}
// POUR操作
int p;
if (f.a + f.b <= m) p = f.a;
else p = m - f.b;
if (!vis[f.a - p][f.b + p]) {
vis[f.a - p][f.b + p] = 1;
q.push({f.a - p, f.b + p, f.step + 1, f.s + "POUR(1,2)\n"});
}
if (f.a + f.b <= n) p = f.b;
else p = n - f.a;
if (!vis[f.a + p][f.b - p]) {
vis[f.a + p][f.b - p] = 1;
q.push({f.a + p, f.b - p, f.step + 1, f.s + "POUR(2,1)\n"});
}
}
cout << "impossible\n"; // 无法达到目标状态
}
int main() {
cin >> n >> m >> k;
bfs();
return 0;
}
这里空空如也
有帮助,赞一个