POJ - 3414 题目链接
我们总共有六种操作
一、装满第一个碗 FILL(1)
二、装满第二个碗 FILL(2)
三、倒空第一个碗 DROP(1)
四、倒空第二个碗 DROP(2)
五、把第一个碗里的水倒入第二个碗 POUR(1,2)
六、把第二个碗里的水倒入第一个碗 POUR(2,1)
接下来我们只要bfs枚举这六类操作即可
题目不难但是这里面的关系可能有点混乱,关键就是要思路有条理才不会乱。
Powered by CK
#include<iostream>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
const int N = 110;
const string op[6] = {"FILL(1)", "FILL(2)", "DROP(1)", "DROP(2)", "POUR(1,2)", "POUR(2,1)"};
int a, b, c, visit[N][N];
struct state {
int a, b;
string op;
state(int x, int y, string z) : a(x), b(y), op(z) {}
};
void solve() {
queue<state> q;
memset(visit, 0, sizeof visit);
visit[0][0] = 1;
q.push(state(0, 0, ""));
while(!q.empty()) {
state temp = q.front();
q.pop();
// cout << temp.a << " " << temp.b << endl;
if(temp.a == c || temp.b == c) {
int n = temp.op.size();
cout << n << endl;
for(int i = 0; i < n; i++)
cout << op[temp.op[i] - '0'] << endl;
return ;
}
if(temp.a != a && !visit[a][temp.b]++) q.push(state(a, temp.b, temp.op + '0'));
if(temp.b != b && !visit[temp.a][b]++) q.push(state(temp.a, b, temp.op + '1'));
if(temp.a != 0 && !visit[0][temp.b]++) q.push(state(0, temp.b, temp.op + '2'));
if(temp.b != 0 && !visit[temp.a][0]++) q.push(state(temp.a, 0, temp.op + '3'));
if(temp.a != 0) {
int add = min(temp.a, b - temp.b);
if(!visit[temp.a - add][temp.b + add]++)
q.push(state(temp.a - add, temp.b + add, temp.op + '4'));
}
if(temp.b != 0) {
int add = min(a - temp.a, temp.b);
// cout << temp.a + add << " " << temp.b - add << endl;
if(!visit[temp.a + add][temp.b -add]++)
q.push(state(temp.a + add, temp.b - add, temp.op + '5'));
}
}
cout << "impossible" << endl;
}
int main() {
// freopen("in.txt", "r", stdin);
while(cin >> a >> b >> c) {
solve();
}
return 0;
}