HDU1495:

本文介绍了一个关于三个杯子如何通过倒水操作使其中两个杯子的水量达到指定目标值的问题,并提供了一段使用广度优先搜索算法实现的C++代码。该算法能够找到从初始状态到达目标状态所需的最少步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

大意:有三个杯子,开始时第一个杯子装满水(体积为a)。。。。倒来倒去,得到其中2个杯里的水的体积都为
a/2。。。。求最小次数。。。。不存在就输出NO。。。。
在任意状态下(即每次的队头)。。。。都有6种倒法(即遍历6种)a->b,c。。。
b->a,c。。。。c->a,b。。。。。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<map>
#include<iostream>
#include<math.h>
#include <queue>
#include<algorithm>
using namespace std;
#define inf 2147483646
#define ll long long
#define N 505
#define LL __int64
struct  node
{
  int a,b,c,v;
};
int vis[111][111][111];
void Bfs(int a, int b, int c)
{
    node q1, q2;
    queue <node> q;
    q1.a = a;
    q1.b = 0;//初始状态是0,而不是b
    q1.c = 0;
    q1.v = 0;
    q.push(q1);
    memset(vis, 0, sizeof(vis));
    
    
    while (!q.empty())
    {
        q2 = q.front();
        q.pop();
        vis[q2.a][q2.b][q2.c] = 1;
        
        //有2个等于a/2就结束
        if ((q2.a == a/2 && q2.b == a/2) ||(q2.a == a/2 && q2.c == a/2) ||(q2.b == a/2 && q2.c == a/2))
        {
            printf("%d\n", q2.v);
            return ;
        }
        
        //a到其他
        if (q2.a != 0)
        {
            //a->b
            if (q2.a > b - q2.b)//倒不完
            {
                q1.a = q2.a - (b-q2.b);    
                q1.b = b;
                q1.c = q2.c;
                q1.v = q2.v + 1;
                
            }
            else//倒完
            {
                
                q1.b = q2.b + q2.a;//后面是q2.a而不是q1.a
                q1.a = 0;
                q1.c = q2.c;
                q1.v = q2.v + 1;
            }
            if (!vis[q1.a][q1.b][q1.c])
            {
                q.push(q1);
                vis[q1.a][q1.b][q1.c] = 1;
            }
            
            
            //a->c
            if (q2.a > c - q2.c)//倒不完///b
            {
                q1.a = q2.a - (c-q2.c);    
                q1.c = c;
                q1.b = q2.b;
                q1.v = q2.v + 1;
            }
            else//倒完
            {
                
                q1.c = q2.c + q2.a;
                q1.a = 0;
                q1.b = q2.b;
                q1.v = q2.v + 1;
            }
            if (!vis[q1.a][q1.b][q1.c])
            {
                q.push(q1);
                vis[q1.a][q1.b][q1.c] = 1;
            }
            
            
        }
        
        //b到其他
        if (q2.b != 0)
        {
            //b->a
            if (q2.b > a - q2.a)//倒不完
            {
                q1.b = q2.b - (a-q2.a);    
                q1.a = a;
                q1.c = q2.c;
                q1.v = q2.v + 1;
                
            }
            else//倒完
            {
                
                q1.a = q2.a + q2.b;
                q1.b = 0;
                q1.c = q2.c;
                q1.v = q2.v + 1;
            }
            if (!vis[q1.a][q1.b][q1.c])
            {
                q.push(q1);
                vis[q1.a][q1.b][q1.c] = 1;
            }
            
            //b->c
            if (q2.b > c - q2.c)//倒不完//a
            {
                q1.b = q2.b - (c-q2.c);    
                q1.c = c;
                q1.a = q2.a;
                q1.v = q2.v + 1;
                
            }
            else//倒完
            {
                
                q1.c = q2.c + q2.b;
                q1.b = 0;
                q1.a = q2.a;
                q1.v = q2.v + 1;
                
            }
            if (!vis[q1.a][q1.b][q1.c])
            {
                q.push(q1);
                vis[q1.a][q1.b][q1.c] = 1;
            }
        }
        
        //c到其他
        if (q2.c != 0)
        {
            //c->b
            if (q2.c > b - q2.b)//倒不完
            {
                q1.c = q2.c - (b-q2.b);    
                q1.b = b;
                q1.a = q2.a;
                q1.v = q2.v + 1;
                if (!vis[q1.a][q1.b][q1.c])
                {
                    q.push(q1);
                    vis[q1.a][q1.b][q1.c] = 1;
                }
            }
            else//倒完
            {
                
                q1.b = q2.b + q2.c;
                q1.c = 0;
                q1.a = q2.a;
                q1.v = q2.v + 1;
                if (!vis[q1.a][q1.b][q1.c])
                {
                    q.push(q1);
                    vis[q1.a][q1.b][q1.c] = 1;
                }
            }
            
            //c->a
            if (q2.c > a - q2.a)//倒不完
            {
                q1.c = q2.c - (a-q2.a);    
                q1.a = a;
                q1.b = q2.b;
                q1.v = q2.v + 1;
                if (!vis[q1.a][q1.b][q1.c])
                {
                    q.push(q1);
                    vis[q1.a][q1.b][q1.c] = 1;
                }
            }
            else//倒完
            {
                
                q1.a = q2.a + q2.c;
                q1.c = 0;
                q1.b = q2.b;
                q1.v = q2.v + 1;
                
            }
			if (!vis[q1.a][q1.b][q1.c])
			{
				q.push(q1);
				vis[q1.a][q1.b][q1.c] = 1;
			}
        }
        
    }
    puts("NO");
    return ;
}
int main()
{
    int s,n,m;
    while(scanf("%d%d%d",&s,&n,&m)&&s&&n&&m)
    {
        if(s%2!=0)
        {
            printf("NO\n");
        }
        else
          Bfs(s,n,m);
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值