这只是一道记录状态的步骤多一点的bfs罢了。
每一步都最多有六种下一步:
1.清空A, 2.清空B 3.装满A 4.装满B 5.将A中液体倒入B 6.将B中液体倒入A;
//step[][]数组用来记录步数
//Node gogo[][]用来记载每一步具体是干什么的;
比如:父状态是: a: 0 b: 0
将设子状态是装满B则子状态为na: 0 nb: B nc: 4(对应状态编号)
那么gogo[na][nb]=Node(a,a,nc);
也就是每一次这一步的gogo都存了上一步的状态,以及到达这一步需要的操作;
可以根据下标关系找到这一状态的上一次状态,于是想到可以遍历到最后合适的结果时,将到这一步之前的状态压入栈,再遍历一次即是答案;
我给出题目的样例的bfs过程,还有注释的地方可以知道遍历完毕后所有的状态;
每一步都是当前状态的AB杯的液体量,以及操作的由来:(我旋转不了图像。。。)
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<string>
#include<queue>
#include<stack>
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
const double epos=1e-8;
const int maxn=109;
struct Node{
int a,b;
int c;
}tan1,in;
ostream& operator <<(ostream& os,const Node& x){
os <<x.a<<"+"<<x.b<<"+"<<x.c<<" ";
return os;
}
int A,B,C;
int step[maxn][maxn];
int flag[maxn][maxn];
Node gogo[maxn][maxn];
/*
1 FILL(1)
2 FILL(2)
3 DROP(1)
4 DROP(2)
5 POUR(1,2)
6 POUR(2,1)
*/
char s[8][12]={"000","FILL(1)","FILL(2)","DROP(1)","DROP(2)","POUR(1,2)","POUR(2,1)"};
void bfs(){
memset(flag,0,sizeof(flag));
memset(step,0,sizeof(step));
memset(gogo,0,sizeof(gogo));
queue<Node>q;
in.a=in.b=in.c=0;
flag[0][0]=1;
q.push(in);
while(!q.empty()){
tan1=q.front();
q.pop();
if(tan1.a==C||tan1.b==C){
printf("%d\n",step[tan1.a][tan1.b]);
// for(int i=0;i<=A;i++){
// for(int j=0;j<=B;j++)
// cout<<gogo[i][j];
// cout<<endl;
//
// }
stack<int>ss;
int i=tan1.a;
int j=tan1.b;
while(1){
if(i==0&&j==0&&gogo[i][j].c==0)
break;
ss.push(gogo[i][j].c);
int t1=gogo[i][j].a;
int t2=gogo[i][j].b;
i=t1,j=t2;
}
while(!ss.empty()){
printf("%s\n",s[ss.top()]);
ss.pop();
}
return ;
}
//FILL(1);
if(tan1.a<A){
in.a=A;
in.b=tan1.b;
in.c=1;
if(flag[in.a][in.b]==0){
flag[in.a][in.b]=1;
Node go;
go.a=tan1.a;
go.b=tan1.b;
go.c=1;
q.push(in);
step[in.a][in.b]=step[tan1.a][tan1.b]+1;
gogo[in.a][in.b]=go;
}
}
//FILL(2);
if(tan1.b<B){
in.a=tan1.a;
in.b=B;
in.c=2;
if(flag[in.a][in.b]==0){
flag[in.a][in.b]=1;
Node go;
go.a=tan1.a;
go.b=tan1.b;
go.c=2;
q.push(in);
step[in.a][in.b]=step[tan1.a][tan1.b]+1;
gogo[in.a][in.b]=go;
}
}
//DROP(1);
if(tan1.a>0){
in.a=0;
in.b=tan1.b;
in.c=3;
if(flag[in.a][in.b]==0){
flag[in.a][in.b]=1;
Node go;
go.a=tan1.a;
go.b=tan1.b;
go.c=3;
q.push(in);
step[in.a][in.b]=step[tan1.a][tan1.b]+1;
gogo[in.a][in.b]=go;
}
}
//DROP(2);
if(tan1.b>0){
in.a=tan1.a;
in.b=0;
in.c=4;
if(flag[in.a][in.b]==0){
flag[in.a][in.b]=1;
Node go;
go.a=tan1.a;
go.b=tan1.b;
go.c=4;
q.push(in);
step[in.a][in.b]=step[tan1.a][tan1.b]+1;
gogo[in.a][in.b]=go;
}
}
//POUR(1,2);
if(tan1.a>0&&tan1.b<B){
if(tan1.a+tan1.b<B){
in.b=tan1.a+tan1.b;
in.a=0;
in.c=5;
if(flag[in.a][in.b]==0){
flag[in.a][in.b]=1;
Node go;
go.a=tan1.a;
go.b=tan1.b;
go.c=5;
q.push(in);
step[in.a][in.b]=step[tan1.a][tan1.b]+1;
gogo[in.a][in.b]=go;
}
}
else{
in.b=B;
in.a=tan1.a-B+tan1.b;
in.c=5;
if(flag[in.a][in.b]==0){
flag[in.a][in.b]=1;
Node go;
go.a=tan1.a;
go.b=tan1.b;
go.c=5;
q.push(in);
step[in.a][in.b]=step[tan1.a][tan1.b]+1;
gogo[in.a][in.b]=go;
}
}
}
//POUR(2,1);
if(tan1.b>0&&tan1.a<A){
if(tan1.a+tan1.b<A){
in.b=0;
in.a=tan1.a+tan1.b;
in.c=6;
if(flag[in.a][in.b]==0){
flag[in.a][in.b]=1;
Node go;
go.a=tan1.a;
go.b=tan1.b;
go.c=6;
q.push(in);
step[in.a][in.b]=step[tan1.a][tan1.b]+1;
gogo[in.a][in.b]=go;
}
}
else{
in.a=A;
in.b=tan1.b-A+tan1.a;
in.c=6;
if(flag[in.a][in.b]==0){
flag[in.a][in.b]=1;
Node go;
go.a=tan1.a;
go.b=tan1.b;
go.c=6;
q.push(in);
step[in.a][in.b]=step[tan1.a][tan1.b]+1;
gogo[in.a][in.b]=go;
}
}
}
}
printf("impossible\n");
return ;
}
int main(){
scanf("%d%d%d",&A,&B,&C);
bfs();
return 0;
}