Pots POJ - 3414
思路:直接bfs不过还要存储路径
具体代码如下
#include<iostream>
#include<queue>
#include<stack>
#include<cstdio>
#include<cstring>
using namespace std;
const int N = 1010;
char * res[] = {"FILL(1)", "FILL(2)", "DROP(1)", "DROP(2)", "POUR(1,2)", "POUR(2,1)"};
//对应六种操作
struct water{ //a,b存水量, pre存前驱, s存操作
int a, b, pre;
char *s;
};
int n, m, k, cnt; //cnt用来存储point中的下标
int dis[N][N];
water point[100010]; //用来存储数据以便输出路径
int bfs(){
queue<water> q;
water xx;
xx.a = 0, xx.b = 0, xx.s = "";
q.push(xx);
dis[0][0] = 0; //从0,0开始
while(q.size()){
water t = q.front();
q.pop();
point[cnt++] = t;
if(t.a == k || t.b == k) return dis[t.a][t.b]; //如果搜到就返回
for(int i=0; i<6; ++i){
water t2 = t;
if(i == 0) t2.a = n;//操作一a瓶加满水
else if(i == 1) t2.b = m;//操作二b瓶加满水
else if(i == 2) t2.a = 0;//操作三a瓶水倒掉
else if(i == 3) t2.b = 0;//...
else if(i == 4){//操作5把a瓶中的水倒入b瓶
int amount = min(m, t2.a + t2.b) - t2.b;//amount表示可以倒的最多水量
//如果b瓶子体积大于a瓶中的水+b瓶中的水amount = a瓶中的水,反之amount = b瓶总体积-b瓶中水的体积
t2.a -= amount;
t2.b += amount;
}else{
int amount = min(n, t2.b + t2.a) - t2.a;//同上
t2.b -= amount;
t2.a += amount;
}
if(dis[t2.a][t2.b] == -1){ //更新距离
dis[t2.a][t2.b] = dis[t.a][t.b] + 1;
t2.s = res[i];
t2.pre = cnt - 1; //记录前驱
q.push(t2);
}
}
}
return -1;
}
void dfs(int cnt2){
//输出用栈,也可以写一个深搜
char * stk[N];
int i = 0;
while(cnt2){
stk[i++] = point[cnt2].s;
cnt2 = point[cnt2].pre;
}
i -= 1;
while(i >= 0){
char * t = stk[i--];
printf("%s\n", t);
}
}
int main(){
scanf("%d%d%d", &n, &m, &k);
memset(dis, -1, sizeof dis);
int ans = bfs();
if(ans == -1) puts("impossible");
else{
printf("%d\n", ans);
dfs(cnt -1);
}
return 0;
}