week2作业——bfs的简单应用:倒水问题

一道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;
}
发布了11 篇原创文章 · 获赞 0 · 访问量 134

猜你喜欢

转载自blog.csdn.net/weixin_43669888/article/details/104688129