HDU 1495:非常可乐

题目链接: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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值