You are given two pots, having the volume of A and B liters respectively. The following operations can be performed:
FILL(i) fill the pot i (1 ≤ i ≤ 2) from the tap;
DROP(i) empty the pot i to the drain;
POUR(i,j) pour from pot i to pot j; after this operation either the pot j is full (and there may be some water left in the pot i), or the pot i is empty (and all its contents have been moved to the pot j).
Write a program to find the shortest possible sequence of these operations that will yield exactly C liters of water in one of the pots.
Input
On the first and only line are the numbers A, B, and C. These are all integers in the range from 1 to 100 and C≤max(A,B).
Output
The first line of the output must contain the length of the sequence of operations K. The following K lines must each describe one operation. If there are several sequences of minimal length, output any one of them. If the desired result can’t be achieved, the first and only line of the file must contain the word ‘impossible’.
Sample Input
3 5 4
Sample Output
6
FILL(2)
POUR(2,1)
DROP(1)
POUR(2,1)
FILL(2)
POUR(2,1)
题目大意:就是给你两个空杯子1,2(有额定容量).你有6中操作。将杯子1加满,将杯子2加满,将杯子1倒空,将杯子2倒空,将1中的水加到2中,将2中的水加到1中(只能全倒或另个杯子满才停止),求出最少的操作步骤使得量出所需的容量。
思路:一个多入口的BFS,不过要记录步骤,就在节点力多添个数组来记录。
#include<iostream>
#include<cstring>
#include<queue>
#include<cstdio>
using namespace std;
const int MAX=1000;
struct node{
int a,b; //杯子水的状态
int step;//记录操作的步数
char str[100][100];//记录操作的步骤
};
bool visit[MAX][MAX];//水的访问状态
int BFS(int a,int b,int c){
queue<node> Q;
memset(visit,false,sizeof(visit));
node t1;
t1.a = 0;
t1.b = 0;
t1.step = 0;
visit[t1.a][t1.b] = true;
Q.push(t1);//初始情况入队
while(!Q.empty()){
node tem = Q.front();
Q.pop();
//找到
if(tem.a==c || tem.b==c){
cout<<tem.step<<endl;
for(int i=0 ; i<=tem.step ; i++){
cout<<tem.str[i]<<endl;
}
return 1;
}
//6种操作
for(int i=1 ; i<=6 ; i++){
node temp = tem;
switch(i){
//将a瓶倒掉
case 1:{
//a非空才倒
if(temp.a != 0){
temp.a = 0;
temp.step = tem.step+1;
strcpy(temp.str[temp.step],"DROP(1)");
}
break;
}
//将b瓶倒掉
case 2:{
//b非空才倒
if(temp.b != 0){
temp.b = 0;
temp.step = tem.step+1;
strcpy(temp.str[temp.step],"DROP(2)");
}
break;
}
//将a瓶加满
case 3:{
//a不满才加
if(temp.a !=a){
temp.a = a;
temp.step = tem.step+1;
strcpy(temp.str[temp.step],"FILL(1)");
}
break;
}
//将b瓶加满
case 4:{
//b不满才加
if(temp.b != b){
temp.b = b;
temp.step = tem.step+1;
strcpy(temp.str[temp.step],"FILL(2)");
}
break;
}
//a加到b
case 5:{
//a不空b不满时加
if(temp.a!=0 && temp.b!=b){
//加够了
if(tem.a + tem.b > b){
temp.a -= b-tem.b;
temp.b = b;
}else{//没加够
temp.a = 0;
temp.b += tem.a;;
}
temp.step = tem.step+1;
strcpy(temp.str[temp.step],"POUR(1,2)");
}
break;
}
//b加到a
case 6:{
//b不空a不满时加
if(temp.b!=0 && temp.a!=a){
//加够了
if(tem.a + tem.b > a){
temp.b -= a-tem.a;
temp.a = a;
}else{//没加够
temp.b = 0;
temp.a += tem.b;
}
temp.step = tem.step+1;
strcpy(temp.str[temp.step],"POUR(2,1)");
}
break;
}
}
if(temp.a==c || temp.b==c){
cout<<temp.step<<endl;
for(int i=0 ; i<=temp.step ; i++){
cout<<temp.str[i]<<endl;
}
return 1;
}
//此状态没有访问过
if(!visit[temp.a][temp.b]){
visit[temp.a][temp.b] = true;
Q.push(temp);
}
}
}
return 0;
}
int main(void){
int a,b,c;
cin>>a>>b>>c;
if(BFS(a,b,c)==0){
cout<<"impossible"<<endl;
}
return 0;
}