- 题意:
有两个体积分别为A、B的容器,容器的起始状态为空,要求通过执行fill a/b、empty a(b) b(a)、pour a(b) b(a)六种操作使其中一个容器中装有体积为C的水,记录并输出操作过程
- 思路:
BFS隐式图问题,以两个容器中盛有水的体积作为本题的状态则初始结点为(0,0),目标结点为(C,0)或(0,C),中间结点为经过不同操作后容器中的盛水状态,从初始结点开始执行一次BFS直到队头元素为目标结点,从此时的队头元素开始向前回溯记录路径,最后输出操作过程。
- 代码实现:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <vector>
using namespace std;
int a,b,c;
bool vis[110][110];
struct s{
int pot1;
int pot2;
int steps;
int op;
int father;
s(){}
s(int p1,int p2,int s,int o,int f):pot1(p1),pot2(p2),steps(s),op(o),father(f){}
};
void Output(int op){
switch(op){
case 0:
cout<<"FILL(1)"<<endl;
break;
case 1:
cout<<"FILL(2)"<<endl;
break;
case 2:
cout<<"DROP(1)"<<endl;
break;
case 3:
cout<<"DROP(2)"<<endl;
break;
case 4:
cout<<"POUR(1,2)"<<endl;
break;
case 5:
cout<<"POUR(2,1)"<<endl;
break;
}
}
int main()
{
ios::sync_with_stdio(false);
while(cin>>a>>b>>c){
memset(vis,0,sizeof(vis));
s q[50000];
int head,tail;
head=tail=0;
vis[0][0]=1;
q[tail++]=s(0,0,0,-1,-1);
bool flag=false;
while(head!=tail){
s t=q[head];
if(t.pot1==c||t.pot2==c){
flag=true;
break;
}
if(!vis[a][t.pot2]){
vis[a][t.pot2]=1;
q[tail++]=s(a,t.pot2,t.steps+1,0,head);
}
if(!vis[t.pot1][b]){
vis[t.pot1][b]=1;
q[tail++]=s(t.pot1,b,t.steps+1,1,head);
}
if(!vis[0][t.pot2]){
vis[0][t.pot2]=1;
q[tail++]=s(0,t.pot2,t.steps+1,2,head);
}
if(!vis[t.pot1][0]){
vis[t.pot1][0]=1;
q[tail++]=s(t.pot1,0,t.steps+1,3,head);
}
int sum=t.pot1+t.pot2;
if(sum>b){
if(!vis[sum-b][b]){
vis[sum-b][b]=1;
q[tail++]=s(sum-b,b,t.steps+1,4,head);
}
}
if(sum<=b){
if(!vis[0][sum]){
vis[0][sum]=1;
q[tail++]=s(0,sum,t.steps+1,4,head);
}
}
if(sum>a){
if(!vis[a][sum-a]){
vis[a][sum-a]=1;
q[tail++]=s(a,sum-a,t.steps+1,5,head);
}
}
if(sum<=a){
if(!vis[sum][0]){
vis[sum][0]=1;
q[tail++]=s(sum,0,t.steps+1,5,head);
}
}
head++;
}
if(!flag){
cout<<"impossible"<<endl;
continue;
}
vector<s> res;
s path=q[head];
while(path.father!=-1){
res.push_back(path);
path=q[path.father];
}
cout<<res.size()<<endl;
for(int i=res.size()-1;i>=0;i--){
Output(res[i].op);
}
}
return 0;
}