题意:就是倒水问题,给你连个杯子,一个杯子的容量是a,另一个杯子的容量是b,一共有六种操作问你最少几次能使其中的一个杯子的水是c,打印出来操作。
思路:BFS+记录路径
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <fstream>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
#define MAXN 110
#define MAXE 210
#define INF 10000000
#define MOD 1000000007
#define LL long long
#define pi acos(-1.0)
using namespace std;
int a, b, c;
int dis[MAXN][MAXN];
vector<string> vec;
int pre[MAXN * MAXN];
int num[MAXN][MAXN];
struct Node {
int a;
int b;
};
int bfs() {
memset(dis, -1, sizeof(dis));
memset(pre, -1, sizeof(pre));
memset(num, -1, sizeof(num));
queue<Node> que;
dis[0][0] = 0;
num[0][0] = 0;
Node t;
t.a = 0, t.b = 0;
que.push(t);
int cnt = 0;
vec.push_back("*");
while (!que.empty()) {
Node p = que.front();
que.pop();
if (p.a == c || p.b == c) {
cout << dis[p.a][p.b] << endl;
vector<string> v;
int s = num[p.a][p.b];
v.push_back(vec[s]);
while (s != -1 && s != 0) {
s = pre[s];
v.push_back(vec[s]);
}
for (int i = v.size() - 2; i >= 0; --i)
cout << v[i] << endl;
return dis[p.a][p.b];
}
if (dis[a][p.b] == -1) {
vec.push_back("FILL(1)");
cnt++;
num[a][p.b] = cnt;
pre[cnt] = num[p.a][p.b];
dis[a][p.b] = dis[p.a][p.b] + 1;
Node temp;
temp.a = a, temp.b = p.b;
que.push(temp);
}
if (dis[p.a][b] == -1) {
vec.push_back("FILL(2)");
cnt++;
num[p.a][b] = cnt;
pre[cnt] = num[p.a][p.b];
dis[p.a][b] = dis[p.a][p.b] + 1;
Node temp;
temp.a = p.a, temp.b = b;
que.push(temp);
}
if (dis[0][p.b] == -1) {
vec.push_back("DROP(1)");
cnt++;
num[0][p.b] = cnt;
pre[cnt] = num[p.a][p.b];
dis[0][p.b] = dis[p.a][p.b] + 1;
Node temp;
temp.a = 0, temp.b = p.b;
que.push(temp);
}
if (dis[p.a][0] == -1) {
vec.push_back("DROP(2)");
cnt++;
num[p.a][0] = cnt;
pre[cnt] = num[p.a][p.b];
dis[p.a][0] = dis[p.a][p.b] + 1;
Node temp;
temp.a = p.a, temp.b = 0;
que.push(temp);
}
if (dis[max(0, p.a - (b - p.b))][min(b, p.b + p.a)] == -1) {
vec.push_back("POUR(1,2)");
cnt++;
num[max(0, p.a - (b - p.b))][min(b, p.b + p.a)] = cnt;
pre[cnt] = num[p.a][p.b];
dis[max(0, p.a - (b - p.b))][min(b, p.b + p.a)] = dis[p.a][p.b] + 1;
Node temp;
temp.a = max(0, p.a - (b - p.b)), temp.b = min(b, p.b + p.a);
que.push(temp);
}
if (dis[min(a, p.a + p.b)][max(0, p.b - (a - p.a))] == -1) {
vec.push_back("POUR(2,1)");
cnt++;
num[min(a, p.a + p.b)][max(0, p.b - (a - p.a))] = cnt;
pre[cnt] = num[p.a][p.b];
dis[min(a, p.a + p.b)][max(0, p.b - (a - p.a))] = dis[p.a][p.b] + 1;
Node temp;
temp.a = min(a, p.a + p.b), temp.b = max(0, p.b - (a - p.a));
que.push(temp);
}
}
return -1;
}
int main() {
std::ios::sync_with_stdio(false);
while (cin >> a >> b >> c) {
vec.clear();
int num = bfs();
if (num == -1) {
cout << "impossible\n";
}
}
return 0;
}