B-Pour Water(BFS解决倒水问题)

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)程序来判定你写的代码是否正确。

二、思路与算法

首先,应该由题意辨别出这个问题是隐式图问题,可以使用BFS方法解决。

隐式图问题:仅给出初始节点、目标节点、生成子节点的约束条件(由题意隐含给出)。

本题中初始节点为A、B杯中都为0(杯空),目标节点为A、B中任意一方水量为C,约束条件为A、B中水量不能超过自身容量等。

编程思路为:输入并存储——>BFS搜索——>输出进行的所有操作。

输入并存储很简单,可用int型直接存储。
BFS搜索需要做抽象概念的转变,我们每次操作有6种可能:把A倒入B(AtoB)、把B倒入A(BtoA)、倒空A(emptyA)、倒空B(emptyB)、倒满A(fillA)、倒满B(fillB)。这六个动作类似于迷宫问题中一个点的周围四个点,它们分别通向6个相邻状态。
所以,我们利用队列queue,每次都check这六种动作,看是否可以达成目标节点。

输出进行的所有操作,类比于输出最短路径,我们也需要声明一些新变量,用于存储有关操作顺序的数据。
本次输出数据用string类存储,用vector数组存储所有要输出的内容,这样和用栈/队列等数据结构存储大同小异,选用顺手的存储即可。

至此,分析完成,按此思路编写的代码如下。(更详细的解释在注释中体现)

三、代码实现

#include<iostream>
#include<vector>
#include<map>
#include<queue>
#include<cstdio>
#include<string>
using namespace std;

struct status{
   
	int x,y;
	string action;     //记录为了达到这个状态,上一个状态进行了什么操作
	status(){
   }         //重载构造函数
	status(int xx,int yy){
   	x=xx;	y=yy;	}
	bool operator < (const status &s)const{
   
		if(x!=s.x){
   	return 	x<s.x;	}
		else{
   	return y<s.y;	}
	}                                   //重载操作符(大小比较方法)
	bool operator == (const status &s)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值