还是比较简单的一道bfs。给定两个容积不超过100的水罐,通过注满一个、倒空一个或是把一个倒入另一个三种手段获得指定体积的水。其中第三种方式只能注满了一个或是倒空了一个。求最少的步骤。如果可能则输出所需步骤数及每一步的倒法,如果不可能则输出“impossible”。
方法,直接bfs。
#include <cstdio>
#include <cstring>
#include <stack>
#include <queue>
#include <iostream>
using namespace std;
typedef struct POT{
int a,b;
int pre_a,pre_b;
int x;
int step;
}Pot;
queue <Pot> p;
stack <Pot> way;
int A,B,C;
Pot can[110][110];
bool vis[110][110];
void rePath(int k){
switch(k){
case 1:cout<<"FILL(1)"<<endl;return;
case 2:cout<<"FILL(2)"<<endl;return;
case 3:cout<<"DROP(1)"<<endl;return;
case 4:cout<<"DROP(2)"<<endl;return;
case 5:cout<<"POUR(1,2)"<<endl;return;
case 6:cout<<"POUR(2,1)"<<endl;return;
}
}
int main(){
Pot z;
cin>>A>>B>>C;
memset(can,0,sizeof(can));
memset(vis,0,sizeof(vis));
p.push(can[0][0]);vis[0][0]=1;
while(!p.empty()){
z=p.front();
p.pop();
if(z.a==C || z.b==C){
way.push(z);break;
}
if(!vis[A][z.b]){
vis[A][z.b]=1;
can[A][z.b].a=A;
can[A][z.b].b=z.b;
can[A][z.b].pre_a=z.a;
can[A][z.b].pre_b=z.b;
can[A][z.b].x=1;
can[A][z.b].step=z.step+1;
p.push(can[A][z.b]);
}
if(!vis[z.a][B]){
vis[z.a][B]=1;
can[z.a][B].a=z.a;
can[z.a][B].b=B;
can[z.a][B].pre_a=z.a;
can[z.a][B].pre_b=z.b;
can[z.a][B].x=2;
can[z.a][B].step=z.step+1;
p.push(can[z.a][B]);
}
if(!vis[0][z.b]){
vis[0][z.b]=1;
can[0][z.b].a=0;
can[0][z.b].b=z.b;
can[0][z.b].pre_a=z.a;
can[0][z.b].pre_b=z.b;
can[0][z.b].x=3;
can[0][z.b].step=z.step+1;
p.push(can[0][z.b]);
}
if(!vis[z.a][0]){
vis[z.a][0]=1;
can[z.a][0].a=z.a;
can[z.a][0].b=0;
can[z.a][0].pre_a=z.a;
can[z.a][0].pre_b=z.b;
can[z.a][0].x=4;
can[z.a][0].step=z.step+1;
p.push(can[z.a][0]);
}
int all;
all=z.a+z.b;
if(!vis[(all>B)?all-B:0][(all>B)?B:all]){
vis[(all>B)?all-B:0][(all>B)?B:all]=1;
can[(all>B)?all-B:0][(all>B)?B:all].a=(all>B)?all-B:0;
can[(all>B)?all-B:0][(all>B)?B:all].b=(all>B)?B:all;
can[(all>B)?all-B:0][(all>B)?B:all].pre_a=z.a;
can[(all>B)?all-B:0][(all>B)?B:all].pre_b=z.b;
can[(all>B)?all-B:0][(all>B)?B:all].x=5;
can[(all>B)?all-B:0][(all>B)?B:all].step=z.step+1;
p.push(can[(all>B)?all-B:0][(all>B)?B:all]);
}
if(!vis[(all>A)?A:all][(all>A)?all-A:0]){
vis[(all>A)?A:all][(all>A)?all-A:0]=1;
can[(all>A)?A:all][(all>A)?all-A:0].a=(all>A)?A:all;
can[(all>A)?A:all][(all>A)?all-A:0].b=(all>A)?all-A:0;
can[(all>A)?A:all][(all>A)?all-A:0].pre_a=z.a;
can[(all>A)?A:all][(all>A)?all-A:0].pre_b=z.b;
can[(all>A)?A:all][(all>A)?all-A:0].x=6;
can[(all>A)?A:all][(all>A)?all-A:0].step=z.step+1;
p.push(can[(all>A)?A:all][(all>A)?all-A:0]);
}
}
if(p.empty()) cout<<"impossible"<<endl;
cout<<z.step<<endl;
for(;z.step;){
way.push(can[z.pre_a][z.pre_b]);
z=can[z.pre_a][z.pre_b];
}
for(;!way.empty();){
rePath(way.top().x);
way.pop();
}
return 0;
}