/*
1.每次倒水时的状态
cup: v1,v2,v3,step;
2.倒水共有6种情况,可通过双重循环实现
3.实现倒水函数
4.令v3恒小于v2,临界条件v1==v2且v3==0
*/
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
#define MAXN 105
using namespace std;
int vis[MAXN][MAXN][MAXN];//每一维分别表示:桶1,2,3中的水的体积。
int S, M, N;
int V[4];
//记录每次倒水后的状态
typedef struct node {
int v[4];
int step;
}note;
note tmp;
void pour(int i, int j)//水从第i桶向第j桶倒
{
int sum = tmp.v[i] + tmp.v[j];//两桶水的总体积
if (sum > V[j])//倒部分水
{
tmp.v[i] = tmp.v[i] - (V[j] - tmp.v[j]);
tmp.v[j] = V[j];
}
else//全倒完
{
tmp.v[j] += tmp.v[i];
tmp.v[i] = 0;
}
}
void bfs()
{
queue<note> q;
while (!q.empty()) q.pop();
note t;
t.step = 0; t.v[1] = S; t.v[2] = 0; t.v[3] = 0;
q.push(t);
vis[t.v[1]][t.v[2]][t.v[3]] = 1;
while (!q.empty())
{
note cur = q.front(); q.pop();
//临界条件
if (cur.v[1] == cur.v[2] && cur.v[3] == 0)
{
printf("%d\n", cur.step);
return;
}
//遍历6种倒水情况
for (int i = 1; i <= 3; i++)
{
for (int j = 1; j <= 3; j++)
{
if (i != j)
{
//倒水的下一步
tmp = cur; tmp.step++;
pour(i, j);
if (!vis[tmp.v[1]][tmp.v[2]][tmp.v[3]])
{
q.push(tmp);
vis[tmp.v[1]][tmp.v[2]][tmp.v[3]] = 1;
}
}
}
}
}
printf("NO\n");
return;
}
int main()
{
while (scanf("%d%d%d", &S, &M, &N) != EOF && (S || M || N))
{
memset(vis, 0, sizeof(vis));
if (M < N) swap(M, N);
V[1] = S; V[2] = M; V[3] = N;
bfs();
}
return 0;
}
hdu1495 bfs解决倒水问题
最新推荐文章于 2025-03-22 14:40:23 发布