题解
题意 |
问两杯水经过6个步骤 |
能否将其中一杯正好是N升水 |
若能 求出步骤最短的方法 |
题解 |
挺麻烦,首先有6种状态,需要一一尝试 |
其次 需要记录步骤 |
我的队列元素是3元的,第一第二分别是A B的升数 |
第三个是一个string的vector 用来存储路径 |
#include <algorithm>
#include <queue>
#include <iostream>
#include <cstring>
using namespace std;
struct node
{
int x, y;
vector<string> v;
};
int main()
{
#ifdef m
freopen("text.txt", "w", stdout);
#endif
int x, y, N;
cin >> x >> y >> N;
queue<node> q;
vector<string> v;
q.push({
0, 0, v});
bool dp[1000][1000];
memset(dp, 0, sizeof(dp));
dp[0][0] = 1;
while (!q.empty())
{
auto t = q.front();
q.pop();
if (t.x == N || t.y == N)
{
cout << t.v.size() << endl;
for (auto e : t.v)
{
cout << e << endl;
}
return 0;
}
int nx, ny;
if (!dp[x][t.y])
{
dp[x][t.y] = 1;
t.v.push_back("FILL(1)");
q.push({
x, t.y, t.v});
t.v.pop_back();
}
if (!dp[t.x][y])
{
dp[t.x][y] = 1;
t.v.push_back("FILL(2)");
q.push({
t.x, y, t.v});
t.v.pop_back();
}
if (!dp[0][t.y])
{
dp[0][t.y] = 1;
t.v.push_back("DROP(1)");
q.push({
0, t.y, t.v});
t.v.pop_back();
}
if (!dp[t.x][0])
{
dp[t.x][0] = 1;
t.v.push_back("DROP(2)");
q.push({
t.x, 0, t.v});
t.v.pop_back();
}
nx = t.x + t.y;
if (nx > x)
{
nx = x;
ny = t.y - (x - t.x);
}
else
ny = 0;
if (!dp[nx][ny])
{
dp[nx][ny] = 1;
t.v.push_back("POUR(2,1)");
q.push({
nx, ny, t.v});
t.v.pop_back();
}
ny = t.x + t.y;
if (ny > y)
{
ny = y;
nx = t.x - (y - t.y);
}
else
nx = 0;
if (!dp[nx][ny])
{
dp[nx][ny] = 1;
t.v.push_back("POUR(1,2)");
q.push({
nx, ny, t.v});
t.v.pop_back();
}
}
cout << "impossible";
return 0;
}