一道bfs的简单应用(与迷宫题十分类似),用到的数据结构:
- 队列(BFS使用)
- 栈(保存输出路径)
- 集合(记录是否到达)
主要思路(BFS操作):
先将起始状态push到队列中并作标记(在集合中标记,不同于上一道迷宫题目,迷宫的位置可以穷尽但本题水的状态过多,再用如二维数组来记录显然不合适,遂使用集合),分别将队列中元素依次pop出,然后分别检查该点的“周围”(这里的周围显然不是普通意义上的周围,而是经过给定的操作能够到达的状态;具体有六种:将A或B倒满或倒空、A倒至B、B倒至A)的点是否可走(满足:未到达过),直至队列空
B - Pour Water
倒水问题
fill A 表示倒满A杯
empty A 表示倒空A杯
pour A B 表示把A的水倒到B杯并且把B杯倒满或A倒空
Input
输入包含多组数据。
每组数据输入 A, B, C
数据范围 0 < A <= B 、C <= B <=1000 、A和B互质。
Output
你的程序的输出将由一系列的指令组成。
这些输出行将导致任何一个罐子正好包含C单位的水。
每组数据的最后一行输出应该是“success”。
输出行从第1列开始,不应该有空行或任何尾随空格。
Sample Input
2 7 5
2 7 4
Sample Output
fill B
pour B A
success
fill A
pour A B
fill A
pour A B
success
Notes
如果你的输出与Sample Output不同,那没关系。
对于某个"A B C"本题的答案是多解的,
不能通过标准的文本对比来判定你程序的正确与否。
所以本题由 SPJ(Special Judge)程序来判定你写的代码是否正确。
- A Possible Solution
#include<iostream>
#include<string>
#include<queue>
#include<set>
#include<map>
using namespace std;
typedef struct tagState {
int cup1, cup2;
bool operator<(const tagState x) const {
if (cup1 != x.cup1)
return cup1 < x.cup1;
else
return cup2 < x.cup2;
}
}State;
void solution(int a, int b, int c) {
queue<State> q; //bfs需要
set<State> s; //记录已到达的“点”
map<State, string> mp; //记录路径
// 1:fill a; 2:fill b; 3:empty a;
// 4:empty b; 5:pour a to b 6:pour b to a
q.push({ 0,0 });
s.insert({ 0,0 });
State tmp={0,0};
mp[tmp] = "";
while (!q.empty()) {
State now = q.front();
q.pop();
if (now.cup1 == c || now.cup2 == c) {
for (int i=0;i<(mp[now]).length(); i++) {
switch ((mp[now])[i]) {
case '1' : cout << "fill A" << endl; break;
case '2' : cout << "fill B" << endl; break;
case '3' : cout << "empty A" << endl; break;
case '4' : cout << "empty B" << endl; break;
case '5' : cout << "pour A B" << endl; break;
case '6' : cout << "pour B A" << endl; break;
}
}
cout << "success" << endl;
break;
}
//fill a
if (s.find({ a,now.cup2 }) == s.end()) {
s.insert({ a,now.cup2 });
q.push({ a,now.cup2 });
tmp={a, now.cup2};
mp[tmp] = mp[now] + "1";
}
//fill b
if (s.find({ now.cup1,b }) == s.end()) {
s.insert({ now.cup1,b });
q.push({ now.cup1,b });
tmp={ now.cup1, b };
mp[tmp] = mp[now] + "2";
}
//empty a
if (s.find({ 0,now.cup2 }) == s.end()) {
s.insert({ 0,now.cup2 });
q.push({ 0,now.cup2 });
tmp={0, now.cup2};
mp[tmp] = mp[now] + "3";
}
//empty b
if (s.find({ now.cup1,0 }) == s.end()) {
s.insert({ now.cup1,0 });
q.push({ now.cup1,0 });
tmp={ now.cup1, 0 };
mp[tmp] = mp[now] + "4";
}
//pour a to b
if (now.cup1 + now.cup2 > b) {
if (s.find({ now.cup1 + now.cup2 - b,b }) == s.end()) {
s.insert({ now.cup1 + now.cup2 - b,b });
q.push({ now.cup1 + now.cup2 - b,b });
tmp={ now.cup1 + now.cup2 - b, b};
mp[tmp] = mp[now] + "5";
}
}
else {
if (s.find({ 0,now.cup1 + now.cup2 }) == s.end()) {
s.insert({ 0,now.cup1 + now.cup2 });
q.push({ 0,now.cup1 + now.cup2 });
tmp={0, now.cup1 + now.cup2};
mp[tmp] = mp[now] + "5";
}
}
//pour b to a
if (now.cup1 + now.cup2 > a) {
if (s.find({ a,now.cup1 + now.cup2 - a }) == s.end()) {
s.insert({ a,now.cup1 + now.cup2 - a });
q.push({ a,now.cup1 + now.cup2 - a });
tmp={a, now.cup1 + now.cup2 - a};
mp[tmp] = mp[now] + "6";
}
}
else {
if (s.find({ now.cup1 + now.cup2,0 }) == s.end()) {
s.insert({ now.cup1 + now.cup2,0 });
q.push({ now.cup1 + now.cup2,0 });
tmp={now.cup1 + now.cup2, 0};
mp[tmp] = mp[now] + "6";
}
}
}
}
int main() {
int a, b, c;
while (cin >> a >> b >> c) {
solution(a, b, c);
}
return 0;
}