题意: 有两个容器,一个容量为A,一个容量为B; 有三种操作:
1. FILL(i) : 给容器i装满水,i = 1 或2;
2. DROP(i ): 倒掉容器i的所有水;
3. POUR(i,j):将i中水倒入j中,直到j装满,i中可以有剩余,或者i不足以装满j;
思路: BFS 加上记忆路径,难点在打印路径。
代码很丑。。。
#include "iostream"
#include "queue"
#include "cstring"
using namespace std;
int A,B,C;
int visit[105][105]; //判断是否访问过此状态
struct Node{
int prex; //记录前一个状态的A容器状态
int prey; //记录前一个状态的B容器状态
int x; //x,y为此时状态
int y;
int step; //步数
int op; //前一状态到此状态的操作,有六种
};
Node pot[105][105]; 用于记忆路径
void output(Node s) { //打印路径
if(s.prex == -1 && s.prey == -1) return;
else {
output(pot[s.prex][s.prey]); //递归,总是再打印前一操作后再打印后一步操作
switch(s.op) {
case 1:cout <<"FILL(1)\n";break;
case 2:cout <<"FILL(2)\n";break;
case 3:cout <<"DROP(1)\n";break;
case 4:cout <<"DROP(2)\n";break;
case 5:cout <<"POUR(1,2)\n";break;
case 6:cout <<"POUR(2,1)\n";break;
default:cout <<"something wrong\n";break;
}
}
}
void bfs() { //简单的宽搜
Node s;
s.prex = -1;
s.prey = -1;
s.x = 0;
s.y = 0;
s.step = 0;
s.op = -1;
memset(visit,0,sizeof(visit));
queue<Node>q;
while(!q.empty()) q.pop();
q.push(s);
while(!q.empty()) {
s = q.front();
q.pop();
pot[s.x][s.y] = s; //将此点记录下来
if(s.x == C || s.y == C) {
cout << s.step << endl;
output(s);
return;
}
visit[s.x][s.y] = 1;
for(int i = 1; i <= 6; i++) { //六个操作
if(i == 1 && !visit[A][s.y]) {
visit[A][s.y] = 1;
Node next;
next.prex = s.x;
next.prey = s.y;
next.x = A;
next.y = s.y;
next.step = s.step+1;
next.op = i;
q.push(next);
}
if(i == 2 && !visit[s.x][B]) {
visit[s.x][B] = 1;
Node next;
next.prex = s.x;
next.prey = s.y;
next.x = s.x;
next.y = B;
next.step = s.step+1;
next.op = i;
q.push(next);
}
if(i == 3 && !visit[0][s.y]) {
visit[0][s.y] = 1;
Node next;
next.prex = s.x;
next.prey = s.y;
next.x = 0;
next.y = s.y;
next.step = s.step+1;
next.op = i;
q.push(next);
}
if(i == 4 && !visit[s.x][0]) {
visit[s.x][0] = 1;
Node next;
next.prex = s.x;
next.prey = s.y;
next.x = s.x;
next.y = 0;
next.step = s.step+1;
next.op = i;
q.push(next);
}
if(i == 5 ) {
int nx,ny;
if(s.x + s.y > B) {
nx = s.x + s.y - B;
ny = B;
}
else if(s.x+s.y <= B) {
nx = 0;
ny = s.x + s.y;
}
if(!visit[nx][ny]) {
visit[nx][ny] = 1;
Node next;
next.prex = s.x;
next.prey = s.y;
next.x = nx;
next.y = ny;
next.step = s.step+1;
next.op = i;
q.push(next);
}
}
if(i == 6) {
int nx,ny;
if(s.x + s.y > A) {
ny = s.x + s.y - A;
nx = A;
}
else if(s.x+s.y <= A) {
ny = 0;
nx = s.x + s.y;
}
if(!visit[nx][ny]) {
visit[nx][ny] = 1;
Node next;
next.prex = s.x;
next.prey = s.y;
next.x = nx;
next.y = ny;
next.step = s.step+1;
next.op = i;
q.push(next);
}
}
}
}
cout << "impossible" << endl;
return;
}
int main() {
while(cin >> A >> B >> C) {
bfs();
}
return 0;
}