每次操作分为6种情况,可以利用队列进行BFS搜索,同时进行剪枝和记录,避免振荡和没必要的操作。
#include <cstdio>
#include <queue>
#include <cmath>
#include <vector>
#include <iostream>
using namespace std;
struct Op {
int a, b;
int step;
int way;
int id,last_id;
Op(int _a,int _b,int _step,int _way,int _id,int _last_id):
a(_a),b(_b),step(_step),way(_way),id(_id),last_id(_last_id){}
};
void print(vector<Op>& allOp,int id) {
if (id == 0)return;
print(allOp, allOp[id].last_id);
if (allOp[id].way == 1)printf("FILL(1)\n");
else if (allOp[id].way == 2)printf("FILL(2)\n");
else if (allOp[id].way == 3)printf("DROP(1)\n");
else if (allOp[id].way == 4)printf("DROP(2)\n");
else if (allOp[id].way == 5)printf("POUR(1,2)\n");
else if (allOp[id].way == 6)printf("POUR(2,1)\n");
}
int main() {
int A = 0, B = 0, C = 0;
scanf_s("%d%d%d", &A, &B, &C);
vector<Op>allOp;
bool _flag[105][105] = { {false} };
Op* init = new Op(0, 0, 0, 0, 0, -1);
_flag[0][0] = true;
int id = 1;
allOp.push_back(*init);
bool flag = false;
int it = 0;
while (allOp.begin() + it != allOp.end()) {
auto temp = allOp[it];
if (temp.a == C || temp.b == C) {
flag = true;
break;
}
it++;
//分为6个操作 a倒满:1 b倒满:2 a倒空:3 b倒空:4 a倒入b:5 b导入a:6
if (temp.a != A&&temp.b != B && !_flag[A][temp.b]) {
Op* new_op = new Op(A, temp.b, temp.step + 1, 1, id++, temp.id);
allOp.push_back(*new_op);
_flag[new_op->a][new_op->b] = true;
delete new_op;
}
if (temp.b != B&&temp.a != A && !_flag[temp.a][B]) {
Op* new_op = new Op(temp.a, B, temp.step + 1, 2, id++, temp.id);
allOp.push_back(*new_op);
_flag[new_op->a][new_op->b] = true;
delete new_op;
}
if (temp.a != 0 && temp.b != 0 && !_flag[0][temp.b]) {
Op* new_op = new Op(0, temp.b, temp.step + 1, 3, id++, temp.id);
allOp.push_back(*new_op);
_flag[new_op->a][new_op->b] = true;
delete new_op;
}
if (temp.b != 0 && temp.a != 0 && !_flag[temp.a][0]) {
Op* new_op = new Op(temp.a, 0, temp.step + 1, 4, id++, temp.id);
allOp.push_back(*new_op);
_flag[new_op->a][new_op->b] = true;
delete new_op;
}
if (temp.b != B&&temp.a != 0) {
Op* new_op = new Op(fmax(temp.a - B + temp.b, 0), fmin(temp.a + temp.b, B), temp.step + 1, 5, id, temp.id);
if (!_flag[new_op->a][new_op->b]) {
allOp.push_back(*new_op);
_flag[new_op->a][new_op->b] = true;
id++;
}
delete new_op;
}
if (temp.a != A&&temp.b != 0) {
Op* new_op = new Op(fmin(temp.a + temp.b, A), fmax(temp.a - A + temp.b, 0), temp.step + 1, 6, id, temp.id);
if (!_flag[new_op->a][new_op->b]) {
allOp.push_back(*new_op);
_flag[new_op->a][new_op->b] = true;
id++;
}
delete new_op;
}
}
if (!flag)printf("impossible\n");
else {
auto temp = allOp[it];
printf("%d\n", temp.step);
print(allOp, temp.id);
}
return 0;
}