题面
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.
题意
给出了两个瓶子的容量A,B, 以及一个目标水量C,对A,B做3种操作,使某一个瓶子的水量为C,求最小操作数,并输出具体操作
分析
注意题中A,B都在100以内,且状态深度较大,故考虑bfs+记忆化。
本题思想简单,到这里就差不多了。
但代码有有点麻烦,需要输出具体方案。
可以考虑每个状态都记录下它从什么状态转移过来。
具体实现还需要注意一些代码技巧,网上有些人这题博客写到两百多行,其实大可不必,可以看一看我代码的实现。
代码
//2152:Pots
#include<cstdio>
#include<iostream>
#include<queue>
using namespace std;
const int maxn=100+10;
int A,B,C,top,sz;
bool vis[maxn][maxn];
char c[6][9]={{'D','R','O','P','(','1',')'},{'D','R','O','P','(','2',')'},
{'F','I','L','L','(','1',')'},{'F','I','L','L','(','2',')'},
{'P','O','U','R','(','1',',','2',')'},{'P','O','U','R','(','2',',','1',')'}};
struct node{
int a,b,id,k,step,last;
}f[100000],stk[100000],ans;
queue<node> q;
void pour(int& u,int &v,int cap){
if(u+v>=cap) u=u+v-cap,v=cap;
else v=u+v,u=0;
}
void bfs(){
node x;
while(!q.empty()){
x=q.front();q.pop();
vis[x.a][x.b]=true;
if(x.a==C||x.b==C){
ans=x;break;
}
node to;
to=x;to.a=0;to.step++;to.last=x.id;to.k=1;to.id=++top;f[top]=to;
if(!vis[to.a][to.b]) q.push(to);
to=x;to.b=0;to.step++;to.last=x.id;to.k=2;to.id=++top;f[top]=to;
if(!vis[to.a][to.b]) q.push(to);
to=x;to.a=A;to.step++;to.last=x.id;to.k=3;to.id=++top;f[top]=to;
if(!vis[to.a][to.b]) q.push(to);
to=x;to.b=B;to.step++;to.last=x.id;to.k=4;to.id=++top;f[top]=to;
if(!vis[to.a][to.b]) q.push(to);
to=x;pour(to.a,to.b,B);to.step++;to.last=x.id;to.k=5;to.id=++top;f[top]=to;
if(!vis[to.a][to.b]) q.push(to);
to=x;pour(to.b,to.a,A);to.step++;to.last=x.id;to.k=6;to.id=++top;f[top]=to;
if(!vis[to.a][to.b]) q.push(to);
}
}
int main()
{
cin>>A>>B>>C;
if(!C) {printf("0");return 0;}
node x;x.a=0;x.b=0;x.id=1;x.step=0;x.last=-1;f[++top]=x;
q.push(x);bfs();
if(ans.step) printf("%d\n",ans.step);
else {printf("impossible");return 0;}
while(ans.last!=-1) stk[++sz]=ans,ans=f[ans.last];
int hwq;
for(int i=sz;i;i--){
if(stk[i].k==5||stk[i].k==6) hwq=9;else hwq=7;
for(int j=0;j<hwq;j++)
printf("%c",c[stk[i].k-1][j]);
printf("\n");
}
return 0;
}