原题链接
题解
题目中给了两个杯子,可以利用BFS直接搜索枚举6种情况就可以了,每个杯子中的水量就是他的状态。这里要记录他的操作路径,可以使用两个数组,一个记录他是由哪个点拓展来得,一个记录这个点的操作(也可以直接在结构体中加个字符串记录操作)
代码如下
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
typedef struct Node{
int a, b, c;
Node(int x, int y, int z){
a = x, b = y, c = z;
}
}node;
int n, m, k;
const int N = 110;
//看了其他的,发现可以不用这样找轨迹和操作,可以在结构体中用个字符串直接记录
int st[110][110];//用它来记录轨迹
int op1[N][N];//记录操作
string op[] = {"", "FILL(1)", "FILL(2)", "DROP(1)", "DROP(2)", "POUR(1,2)", "POUR(2,1)"};
int main(){
queue<node> qu;
qu.push(Node(0, 0, 0));//a来保存第一中的水量,b用来保存第二中的水量,c表示的是步数
st[0][0] = 0;
cin >> n >> m >> k;
memset(st, -1, sizeof st);
int nx = -1, ny = -1;
while(qu.size()){
node t = qu.front(); qu.pop();
int a = t.a, b = t.b, c = t.c;
if(a == k || b == k) {cout << c << endl; nx = a, ny = b; break;}
if(st[n][b] == -1)
qu.push(Node(n, b, c + 1)), st[n][b] = a * 110 + b, op1[n][b] = 1;
if(st[a][m] == -1)
qu.push(Node(a, m, c + 1)), st[a][m] = a * 110 + b, op1[a][m] = 2;
if(st[0][b] == -1)
qu.push(Node(0, b, c + 1)), st[0][b] = a * 110 + b, op1[0][b] = 3;
if(st[a][0] == -1)
qu.push(Node(a, 0, c + 1)), st[a][0] = a * 110 + b, op1[a][0] = 4;
int x = m - b;
int p = (x >= a? 0 : a - x), q = (x >= a? b + a : m);
if(st[p][q] == -1)
qu.push(Node(p, q, c + 1)), st[p][q] = a * 110 + b, op1[p][q] = 5;
int y = n - a;
p = (y >= b? a + b : n), q = (y >= b? 0 : b - y);
if(st[p][q] == -1)
qu.push(Node(p, q, c + 1)), st[p][q] = a * 110 + b, op1[p][q] = 6;
}
if(nx == -1) cout << "impossible" << '
';
else{
vector<string> res;
int t = nx, p = ny;
while(nx != 0 || ny != 0){
res.push_back(op[op1[t][p]]);
t = st[nx][ny] / N, p = st[nx][ny] % N;
nx = t, ny = p;
}
reverse(res.begin(), res.end());
for(int i = 0; i < res.size(); ++ i){
cout << res[i] << '
';
}
}
return 0;
}