HDUOJ 1495 非常可乐(这个广搜可还行)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1495

题意就不多说了,就是有三个杯子可以来回倒可乐,当其中两个杯子的可乐的量是总的量的一半的时候,就到了题目要的那种状态,这个问题可以使用广搜来解决,不难发现,这个过程中,我们有六种操作,就是把某个杯子的可乐倒到另外的两个杯子中,一共三个杯子,所以一共六种状态,所以,我们的思路就是,从最初的状态开始,一步一步的向下一个状态转移,然后加入队列,在下一步中取出这个状态,以后的操作都是如此,直到我们需要的状态出现,就结束BFS函数,每次转移都记录当前的操作数,最后只需要输出最后一步的操作数即可。

AC代码:

#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
using namespace std;
int a, b, c, visit[105][105][105];
struct edge
{
    int x;
    int y;
    int z;
    int step;
};
int bfs(void);
int main(void)
{
    while(scanf("%d %d %d", &a, &b, &c))
    {
        if((a==0)&&(b==0)&&(c==0))
        {
            break;
        }
        if(a % 2 != 0)
        {
            printf("NO\n");
            continue;
        }
        memset(visit, 0, sizeof(visit));
        int flag = 1;
        flag = bfs();
        if(flag == -1)
        {
            printf("NO\n");
            continue;
        }
        printf("%d\n", flag);
    }
    return 0;

int bfs(void)
{
    queue<edge> map;
    edge k;
    k.x = a;
    k.y = 0;
    k.z = 0;
    k.step = 0;
    map.push(k);
    visit[a][0][0] = 1;
    while(!map.empty())
    {
        edge now = map.front();
        map.pop();
        if(((now.x == (a/2))&&(now.y == (a/2)))||((now.x == (a/2))&&(now.z == (a/2)))||((now.y == (a/2))&&(now.z == (a/2))))
        {
            return now.step;
        }
        for(int i = 0; i < 6; i++)
        {
            edge next;
            if(i == 0)//把第一瓶水到给第二瓶 
            {
                next.z = now.z;
                if(now.x > b - now.y)
                {
                    next.y = b;
                    next.x = now.x - (b - now.y);
                }
                else
                {
                    next.x = 0;
                    next.y = now.y + now.x;
                }
                if(visit[next.x][next.y][next.z] == 0)
                {
                    next.step = now.step + 1;
                    map.push(next);
                    visit[next.x][next.y][next.z] = 1;
                }
            }
            if(i == 1)//把第一瓶水到给第三瓶 
            {
                next.y = now.y;
                if(now.x > c - now.z)
                {
                    next.z = c;
                    next.x = now.x - (c - now.z);
                }
                else
                {
                    next.x = 0;
                    next.z = now.z + now.x;
                }
                if(visit[next.x][next.y][next.z] == 0)
                {
                    next.step = now.step + 1;
                    map.push(next);
                    visit[next.x][next.y][next.z] = 1;
                }
            }
            if(i == 2)//把第二瓶水到给第一瓶 
            {
                next.z = now.z;
                if(now.y > a - now.x)
                {
                    next.x = a;
                    next.y = now.y - (a - now.x);
                }
                else
                {
                    next.y = 0;
                    next.x = now.x + now.y;
                }
                if(visit[next.x][next.y][next.z] == 0)
                {
                    next.step = now.step + 1;
                    map.push(next);
                    visit[next.x][next.y][next.z] = 1;
                }
            }
            if(i == 3)//把第二瓶水到给第三瓶 
            {
                next.x = now.x;
                if(now.y > c - now.z)
                {
                    next.z = c;
                    next.y = now.y - (c - now.z);
                }
                else
                {
                    next.y = 0;
                    next.z = now.z + now.y;
                }
                if(visit[next.x][next.y][next.z] == 0)
                {
                    next.step = now.step + 1;
                    map.push(next);
                    visit[next.x][next.y][next.z] = 1;
                }
            }
            if(i == 4)//把第三瓶水到给第一瓶 
            {
                next.y = now.y;
                if(now.z > a - now.x)
                {
                    next.x = a;
                    next.z = now.z - (a - now.x);
                }
                else
                {
                    next.z = 0;
                    next.x = now.x + now.z;
                }
                if(visit[next.x][next.y][next.z] == 0)
                {
                    next.step = now.step + 1;
                    map.push(next);
                    visit[next.x][next.y][next.z] = 1;
                }
            }
            if(i == 5)//把第三瓶水到给第二瓶 
            {
                next.x = now.x;
                if(now.z > b - now.y)
                {
                    next.y = b;
                    next.z = now.z - (b - now.y);
                }
                else
                {
                    next.z = 0;
                    next.y = now.y + now.z;
                }
                if(visit[next.x][next.y][next.z] == 0)
                {
                    next.step = now.step + 1;
                    map.push(next);
                    visit[next.x][next.y][next.z] = 1;
                }
            }
        }
    }
    return -1;
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值