题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1495
因为三个容器都没有刻度,但是他们的容积固定,所以每次要不倒空某个容器,
或倒满某个容器。只有通过容积来衡量两个容器中的饮料数是否相等。
AC代码:
#include <iostream>
#include <stdio.h>
#include <queue>
#include <math.h>
#include <string.h>
#include <algorithm>
using namespace std;
int S,N,M,half; ///M是小杯子,N是大杯子
int vis[110][110][110];
struct Node
{
int bottle; ///瓶子中的容量
int smallcup; ///小杯子中的量
int bigcup; ///大杯子中的量
int time; ///到达该状态的倒水次数
};
void bfs()
{
memset(vis,0,sizeof(vis));
queue<Node>qu;
Node cur,nex;
cur.bottle = S;
cur.bigcup = 0;
cur.smallcup = 0;
cur.time = 0;
vis[S][0][0] = 1;
qu.push(cur);
while(!qu.empty())
{
cur = qu.front();
qu.pop();
if((cur.bottle==half&&cur.bigcup==half) || (cur.bottle==half&&cur.smallcup==half) || (cur.bigcup==half&&cur.smallcup==half))
{
printf("%d\n",cur.time);
return;
}
if(cur.bottle != 0) ///瓶中有可乐
{
///倒入大杯子,能完全倒完。M是小杯子,N是大杯子
if(cur.bottle <= N-cur.bigcup)
{
nex.bottle = 0;
nex.bigcup = cur.bigcup + cur.bottle;
}
else ///倒不完
{
nex.bigcup = N; ///大杯子被倒满
nex.bottle = cur.bottle - (N-cur.bigcup); ///瓶子剩余
}
nex.smallcup = cur.smallcup;
nex.time = cur.time + 1;
if(vis[nex.bottle][nex.bigcup][nex.smallcup] == 0)
{
vis[nex.bottle][nex.bigcup][nex.smallcup] = 1;
qu.push(nex);
}
///倒入小杯子,能完全倒完
if(cur.bottle <= M-cur.smallcup)
{
nex.bottle = 0;
nex.smallcup = cur.smallcup + cur.bottle;
}
else
{
nex.smallcup = M;
nex.bottle = cur.bottle - (M-cur.smallcup);
}
nex.bigcup = cur.bigcup;
nex.time = cur.time + 1;
if(vis[nex.bottle][nex.bigcup][nex.smallcup] == 0)
{
vis[nex.bottle][nex.bigcup][nex.smallcup] = 1;
qu.push(nex);
}
}
if(cur.bigcup != 0) ///大杯子往其他杯子倒水
{
///大杯子往瓶子里面倒水。
if(cur.bigcup <= S-cur.bottle)
{
nex.bigcup = 0;
nex.bottle = cur.bottle + cur.bigcup;
}
else
{
nex.bottle = S;
nex.bigcup = cur.bigcup - (S-cur.bottle);
}
nex.smallcup = cur.smallcup;
nex.time = cur.time + 1;
if(vis[nex.bottle][nex.bigcup][nex.smallcup] == 0)
{
vis[nex.bottle][nex.bigcup][nex.smallcup] = 1;
qu.push(nex);
}
///大杯子往小杯子倒水
if(cur.bigcup <= M-cur.smallcup)
{
nex.bigcup = 0;
nex.smallcup = cur.smallcup + cur.bigcup;
}
else
{
nex.smallcup = M;
nex.bigcup = cur.bigcup - (M-cur.smallcup);
}
nex.bottle = cur.bottle;
nex.time = cur.time + 1;
if(vis[nex.bottle][nex.bigcup][nex.smallcup] == 0)
{
vis[nex.bottle][nex.bigcup][nex.smallcup] = 1;
qu.push(nex);
}
}
if(cur.smallcup != 0)
{
///往大杯倒水
if(cur.smallcup <= N-cur.bigcup)
{
nex.smallcup = 0;
nex.bigcup = cur.bigcup + cur.smallcup;
}
else
{
nex.smallcup = cur.smallcup - (N-cur.bigcup);
nex.bigcup = N;
}
nex.bottle = cur.bottle;
nex.time = cur.time + 1;
if(vis[nex.bottle][nex.bigcup][nex.smallcup] == 0)
{
vis[nex.bottle][nex.bigcup][nex.smallcup] = 1;
qu.push(nex);
}
///往瓶子里倒
if(cur.smallcup <= S-cur.bottle)
{
nex.bottle = cur.bottle + cur.smallcup;
nex.smallcup = 0;
}
else
{
nex.bottle = S;
nex.smallcup = cur.smallcup - (S-cur.bottle);
}
nex.bigcup = cur.bigcup;
nex.time = cur.time + 1;
if(vis[nex.bottle][nex.bigcup][nex.smallcup] == 0)
{
vis[nex.bottle][nex.bigcup][nex.smallcup] = 1;
qu.push(nex);
}
}
}
printf("NO\n");
}
int main()
{
while(~scanf("%d%d%d",&S,&N,&M))
{
if(S+N+M == 0) break;
if(S&1) ///容量是奇数
printf("NO\n");
else
{
int t1=M,t2=N;
M = min(t1,t2); ///M是小杯子
N = max(t1,t2); ///N是大杯子
half = S/2;
bfs();
}
}
return 0;
}