给你两个容器,分别能装下A升水和B升水,并且可以进行以下操作
FILL(i) 将第i个容器从水龙头里装满(1 ≤ i ≤ 2);
DROP(i) 将第i个容器抽干
POUR(i,j) 将第i个容器里的水倒入第j个容器(这次操作结束后产生两种结果,一是第j个容器倒满并且第i个容器依旧有剩余,二是第i个容器里的水全部倒入j中,第i个容器为空)
现在要求你写一个程序,来找出能使其中任何一个容器里的水恰好有C升,找出最少操作数并给出操作过程
Input
有且只有一行,包含3个数A,B,C(1<=A,B<=100,C<=max(A,B))
Output
第一行包含一个数表示最小操作数K
随后K行每行给出一次具体操作,如果有多种答案符合最小操作数,输出他们中的任意一种操作过程,如果你不能使两个容器中的任意一个满足恰好C升的话,输出“impossible”
Sample Input
3 5 4
Sample Output
6
FILL(2)
POUR(2,1)
DROP(1)
POUR(2,1)
FILL(2)
POUR(2,1)
哇~被自己菜哭了~我真的对回溯很不在行啊~对指针更不在行~我开始写的node fr; 所以无论如何向回指,其实都指的自身,因为fr已经被定义了;这也是为何他们都用的数组,改变地址啊~菜哭了~
#include<cstdio>
#include<queue>
#include<cstring>
#include<iostream>
#include<stack>
using namespace std;
int a, b, c;
char ji[6][10] = {"FILL(1)", "FILL(2)", "DROP(1)", "DROP(2)", "POUR(1,2)", "POUR(2,1)"};//六种状态
int vis[110][110];//标记两个瓶子水量状态是否经过
struct node{
int x, y, step, flag;//x 第一个杯子的水量 y 第二个杯子的水量 step 走的深度 flag 标记此刻走路的选择是六种状态的哪一个
node* pre;//回溯专用
};
queue<node>q;
stack<int>lu;//因为回溯是逆序的所以符合栈的规则,先进先出
int bfs(){
node fr[400], ne;
ne.flag = 0; ne.pre = NULL; ne.step = 0; ne.x = 0; ne.y = 0;
q.push(ne);
vis[0][0] = 1;
int sum = 0;
int cnt = -1;
while(!q.empty()){
cnt++;
fr[cnt] = q.front();
//cout <<"fr.x = " << fr[cnt].x << " fr.y = " << fr[cnt].y << " fr.step = " << fr[cnt].step << endl;
q.pop();
if(fr[cnt].x == c || fr[cnt].y == c){
sum = fr[cnt].step;
// cout << "sum = " << sum<< endl;
while(fr[cnt].pre != NULL){
lu.push(fr[cnt].flag);
//cout << "fr.flag = " <<fr[cnt].flag << endl;
fr[cnt] = *(fr[cnt].pre);
}
return sum;
}
for(int i = 1; i <= 6; i++){//分别对应六种状态的选择
switch(i){
case 1:
ne.x = a;
ne.y = fr[cnt].y;
ne.flag = 1;
break;
case 2:
ne.x = fr[cnt].x;
ne.y = b;
ne.flag = 2;
break;
case 3:
ne.x = 0;
ne.y = fr[cnt].y;
ne.flag = 3;
break;
case 4:
ne.x = fr[cnt].x;
ne.y = 0;
ne.flag = 4;
break;
case 5:
if(fr[cnt].x + fr[cnt].y > b){
ne.x = fr[cnt].x - (b-fr[cnt].y);
ne.y = b;
}
else{
ne.x = 0;
ne.y = fr[cnt].x + fr[cnt].y;
}
ne.flag = 5;
break;
case 6:
if(fr[cnt].x + fr[cnt].y > a){
ne.x = a;
ne.y = fr[cnt].y - (a-fr[cnt].x);
}
else{
ne.x = fr[cnt].x + fr[cnt].y;
ne.y = 0;
}
ne.flag = 6;
break;
}
if(vis[ne.x][ne.y])
continue;
vis[ne.x][ne.y] = 1;
ne.step = fr[cnt].step + 1;
ne.pre = &fr[cnt];
q.push(ne);
}
}
return 0;
}
void print(){
while(!lu.empty()){
int i = lu.top();
lu.pop();
printf("%s\n", ji[i-1]);
}
}
int main(){
while(scanf("%d%d%d", &a, &b, &c) != EOF){
memset(vis, 0, sizeof(vis));
int sum = bfs();
if(sum == 0)
printf("impossible\n");
else{
printf("%d\n", sum);
print();
}
}
return 0;
}