数据:
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
#include <iostream>
#include <queue>
#include <stack>
using namespace std;
int AtoBb(int B, int a, int b){ //A向B里面倒水后,B中的水
if(a<=B-b) return b+a; //判断水的多少引起的问题,后续的相似
return B;
}
int AtoBa(int B, int a, int b){
if(a<=B-b) return 0;
return a+b-B;
}
int BtoAa(int A, int a, int b){
if(b<=A-a) return a+b;
return A;
}
int BtoAb(int A, int a, int b){
if(b<=A-a) return 0;
return a+b-A;
}
void bfs(int A, int B, int C){ //实现倒水问题,即路径搜索的主函数
queue<int> P; //记录到达的点,此处即为A.B中水的数量
queue<int> Q;
stack<int> Lu; //方便最后反向输出路径
int X[A+1][B+1] ; //用来存放到达的点的前一个点的坐标
int Y[A+1][B+1];
int M[A+1][B+1]; //用来记录倒水的操作
for(int i=0; i<A+1; i++){
for(int j=0; j<B+1; j++){
M[i][j]=0;
}
}
M[0][0]=-1;
P.push(0); //起点入队列
Q.push(0);
int a=0,b=0;
while(a!=C || b!=C || !P.empty()){ //搜索结束条件
int a1=P.front(); //开始搜索
P.pop();
int b1=Q.front();
Q.pop();
int i=1;
for(; i<=6; i++){
if(i==1){ //装满A
a=A;
b=b1;
}else if(i==2){//装满B
a=a1;
b=B;
}else if(i==3){ //A to B
a=AtoBa(B,a1,b1);
b=AtoBb(B,a1,b1);
}else if(i==4){ //B to A
a=BtoAa(A,a1,b1);
b=BtoAb(A,a1,b1);
}else if(i==5){ //倒空A
a=0;
b=b1;
}else if(i==6){ //倒空B
a=a1;
b=0;
}
if(M[a][b]==0){ //判断该点是否到达
M[a][b]=i; //记录倒水的操作
P.push(a);
Q.push(b);
X[a][b]=a1;
Y[a][b]=b1;
}
if(a==C || b==C) break; //到达终点,结束
}
if(a==C || b==C) break;
}
Lu.push(a); //入栈,反向输出路径
Lu.push(b);
while(a!=0 || b!=0){ //将路径入栈
int m=X[a][b];
int n=Y[a][b];
a=m;
b=n;
Lu.push(a);
Lu.push(b);
}
Lu.pop();
Lu.pop();
while(!Lu.empty()){ //输出路径,即倒水的顺序
int n=Lu.top();
Lu.pop();
int m=Lu.top();
Lu.pop();
if(M[m][n]==1){
cout<<"fill A"<<endl;
}else if(M[m][n]==2){
cout<<"fill B"<<endl;
}else if(M[m][n]==3){
cout<<"pour A B"<<endl;
}else if(M[m][n]==4){
cout<<"pour B A"<<endl;
}else if(M[m][n]==5){
cout<<"empty A"<<endl;
}else if(M[m][n]==6){
cout<<"empty B"<<endl;
}
}
cout<<"success"<<endl;
}
int main(){
int A,B,C;
ios::sync_with_stdio(false);
while(cin>>A>>B>>C){ //输出多组数据
bfs(A,B,C);
}
return 0;
}
思路:和迷宫问题一样,都是属于用bfs进行路径搜索的题目,不过倒水问题的下一步移动的方向距离是隐藏的,并不是确定的,故需要处理一下这个问题。其他基本和迷宫问题一样,不断搜索点,然后保存前一个点的坐标,最后到达终点后,从终点将路径反向输出即可。