給你兩個容器,分別能裝下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;
}