题目大意:给两个杯子,和一个目标量,问是否通过那两个杯子互相倒水倒得目标量的水,给三种操作如下:
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).
不翻译了��
搜索的过程不说了,说说输出,我们知道广搜的特点就是每走一步就可能通过当前步延伸出多步,若我们通过父节点纪录子节点的方式就行不通了(这里的父节点指的是先走的步,子节点是先走的步扩展出来的步),所以我们要使子节点纪录父节点,因为一个子节点只有一个父节点,那如何记录呢,我采用的是数组的方式,每一个节点对应一个数组下标rec[j],数组是一个二维数组,rec[j][0]代表父节点的下标,rec[j][1]对应当前步的操作,还要注意我设定的当作开始的节点的节点的父节点是0,那么数组下标0就不能对应操作了,那么我就让控制数组下标的变量从1开始,这样也就找到了输出时的出口,输出时就按这样输出就可以了:
void print(int a){
if(a==0){. //下标0就结束
return;
}
print(rec[a][0]);
switch (rec[a][1]) {
case 0:printf("FILL(1)\n");break;
case 1:printf("FILL(2)\n");break;
case 2:printf("DROP(1)\n");break;
case 3:printf("DROP(2)\n");break;
case 4:printf("POUR(1,2)\n");break;
case 5:printf("POUR(2,1)\n");break;
}
return;
}
代码:
#include <iostream>
#include <string>
#include <algorithm>
#include <queue>
#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace std;
struct node{
int a,b,step,self;
};
int rec[10000][2]={0},j=1;
void print(int a){
if(a==0){
return;
}
print(rec[a][0]);
switch (rec[a][1]) {
case 0:printf("FILL(1)\n");break;
case 1:printf("FILL(2)\n");break;
case 2:printf("DROP(1)\n");break;
case 3:printf("DROP(2)\n");break;
case 4:printf("POUR(1,2)\n");break;
case 5:printf("POUR(2,1)\n");break;
}
return;
}
int main(){
int ca,cb,tar,i,flag=0,ok=0;
int walked[120][120]={0};//a b
cin>>ca>>cb>>tar;
queue<node> q;
node temp;
temp.a=0;
temp.b=0;
temp.step=0;
temp.self=0;
q.push(temp);
while(!q.empty()){
for(i=0;i<6;i++){
if(i==0){ //fill a
temp.a=ca;
temp.b=q.front().b;
temp.step=q.front().step+1;
temp.self=j;
if(walked[temp.a][temp.b]==0){
rec[j][0]=q.front().self;
rec[j][1]=0;
j++;
walked[temp.a][temp.b]=1;
q.push(temp);
}
if(temp.a==tar||temp.b==tar){
flag=1;
ok=q.front().step+1;
break;
}
}
if(i==1){ //fill b
temp.a=q.front().a;
temp.b=cb;
temp.step=q.front().step+1;
temp.self=j;
if(walked[temp.a][temp.b]==0){
rec[j][0]=q.front().self;
rec[j][1]=1;
j++;
walked[temp.a][temp.b]=1;
q.push(temp);
}
if(temp.a==tar||temp.b==tar){
flag=1;
ok=q.front().step+1;
break;
}
}
if(i==2){ //drop a
temp.a=0;
temp.b=q.front().b;
temp.step=q.front().step+1;
temp.self=j;
if(walked[temp.a][temp.b]==0){
rec[j][0]=q.front().self;
rec[j][1]=2;
j++;
walked[temp.a][temp.b]=1;
q.push(temp);
}
if(temp.a==tar||temp.b==tar){
flag=1;
ok=q.front().step+1;
break;
}
}
if(i==3){ //drop b
temp.a=q.front().a;
temp.b=0;
temp.step=q.front().step+1;
temp.self=j;
if(walked[temp.a][temp.b]==0){
rec[j][0]=q.front().self;
rec[j][1]=3;
j++;
walked[temp.a][temp.b]=1;
q.push(temp);
}
if(temp.a==tar||temp.b==tar){
flag=1;
ok=q.front().step+1;
break;
}
}
if(i==4){ //pour a->b
if(cb-q.front().b>=q.front().a){ //a was empty
temp.a=0;
temp.b=q.front().a+q.front().b;
}
else{ //b was full
temp.a=q.front().a-(cb-q.front().b);
temp.b=cb;
}
temp.step=q.front().step+1;
temp.self=j;
if(walked[temp.a][temp.b]==0){
rec[j][0]=q.front().self;
rec[j][1]=4;
j++;
walked[temp.a][temp.b]=1;
q.push(temp);
}
if(temp.a==tar||temp.b==tar){
flag=1;
ok=q.front().step+1;
break;
}
}
if(i==5){ //b->a
if(ca-q.front().a>=q.front().b){ //b was empty
temp.a=q.front().a+q.front().b;
temp.b=0;
}
else{ //a was full
temp.a=ca;
temp.b=q.front().b-(ca-q.front().a);
}
temp.step=q.front().step+1;
temp.self=j;
if(walked[temp.a][temp.b]==0){
rec[j][0]=q.front().self;
rec[j][1]=5;
j++;
walked[temp.a][temp.b]=1;
q.push(temp);
}
if(temp.a==tar||temp.b==tar){
flag=1;
ok=q.front().step+1;
break;
}
}
}
if(flag){
break;
}
q.pop();
}
if(flag){
printf("%d\n",ok);
print(j-1);
}
else{
printf("impossible\n");
}
return 0;
}