当前位置: 首页 > news >正文

《算法笔记》8.2小节——搜索专题->广度优先搜索(BFS)问题 E: 【宽搜入门】巧妙取量

【题目描述】
  有三个容器,容量分别为 a,b,c(a> b > c ),一开始a装满油,现在问是否只靠abc三个容器量出k升油。如果能就输出“yes”,并且说明最少倒几次,否则输出“no”。例如:10升油在10升的容器中,另有两个7升和3升的空容器,要求用这三个容器倒油,使得最后在abc三个容器中有一个刚好存有5升油,问最少的倒油次数是多少?(每次倒油,A容器倒到B容器,或者A内的油倒完,或者B容器倒满。
 10 7 3
(10 0 0)
(3 7 0):第一次
(3 4 3):第二次
(6 4 0):第三次
(6 1 3):第四次
(9 1 0):第五次
(9 0 1):第六次
(2 7 1):第七次
(2 5 3):第八次,出现5了。

Input

【输入格式】
  有多组测试数据。
  输入a,b,c, k四个正整数( 100 ≥ a > b > c≥1 , 1≤k< 100 )

Output

【输出格式】
  如果能得到k就输出两行。
  第一行“yes”,第二行为最少的次数
  否则输出“no”

Sample Input

10 7 3 5

Sample Output

yes
8

分析:这道题的做法和这节的问题A下面提示的有一些区别,这道题能做的操作只有把油从容器X倒到容器Y中,不可以从外面补充,也不可以把油直接倒掉。因此总共只有6种可能的操作:把油从a倒进b;把油从a倒进c;把油从b倒进c;把油从b倒进a;把油从c倒进b;把油从c倒进a.

搞清楚这点之后,用BFS就可以做了。

#include    <algorithm>
#include     <iostream>
#include      <cstdlib>
#include      <cstring>
#include       <string>
#include       <vector>
#include       <cstdio>
#include        <queue>
#include        <stack>
#include        <ctime>
#include        <cmath>
#include          <map>
#include          <set>
#include<unordered_map>
#define INF 0x3f3f3f3f
#define db1(x) cout<<#x<<"="<<(x)<<endl
#define db2(x,y) cout<<#x<<"="<<(x)<<", "<<#y<<"="<<(y)<<endl
#define db3(x,y,z) cout<<#x<<"="<<(x)<<", "<<#y<<"="<<(y)<<", "<<#z<<"="<<(z)<<endl
#define db4(x,y,z,a) cout<<#x<<"="<<(x)<<", "<<#y<<"="<<(y)<<", "<<#z<<"="<<(z)<<", "<<#a<<"="<<(a)<<endl
#define db5(x,y,z,a,r) cout<<#x<<"="<<(x)<<", "<<#y<<"="<<(y)<<", "<<#z<<"="<<(z)<<", "<<#a<<"="<<(a)<<", "<<#r<<"="<<(r)<<endl
using namespace std;
 
typedef struct node
{
    int cap_a,cap_b,cap_c,cnt_a,cnt_b,cnt_c,index;
}node;
 
node pour_a2b(node now,int a,int b)
{
    node temp=now;
    if(a==1&&b==2)
    {
        if(temp.cnt_a<temp.cap_b-temp.cnt_b)temp.cnt_b+=temp.cnt_a,temp.cnt_a=0;
        else temp.cnt_a-=temp.cap_b-temp.cnt_b,temp.cnt_b=temp.cap_b;
    }
    else if(a==2&&b==3)
    {
        if(temp.cnt_b<temp.cap_c-temp.cnt_c)temp.cnt_c+=temp.cnt_b,temp.cnt_b=0;
        else temp.cnt_b-=temp.cap_c-temp.cnt_c,temp.cnt_c=temp.cap_c;
    }
    else if(a==1&&b==3)
    {
        if(temp.cnt_a<temp.cap_c-temp.cnt_c)temp.cnt_c+=temp.cnt_a,temp.cnt_a=0;
        else temp.cnt_a-=temp.cap_c-temp.cnt_c,temp.cnt_c=temp.cap_c;
    }
    temp.index=now.index+1;
    return temp;
}
 
node pour_b2a(node now,int a,int b)
{
    node temp=now;
    if(a==2&&b==1)
    {
        if(temp.cnt_b<temp.cap_a-temp.cnt_a)temp.cnt_a+=temp.cnt_b,temp.cnt_b=0;
        else temp.cnt_b-=temp.cap_a-temp.cnt_a,temp.cnt_a=temp.cap_a;
    }
    else if(a==3&&b==2)
    {
        if(temp.cnt_c<temp.cap_b-temp.cnt_b)temp.cnt_b+=temp.cnt_c,temp.cnt_c=0;
        else temp.cnt_c-=temp.cap_b-temp.cnt_b,temp.cnt_b=temp.cap_b;
    }
    else if(a==3&&b==1)
    {
        if(temp.cnt_c<temp.cap_a-temp.cnt_a)temp.cnt_a+=temp.cnt_c,temp.cnt_c=0;
        else temp.cnt_c-=temp.cap_a-temp.cnt_a,temp.cnt_a=temp.cap_a;
    }
    temp.index=now.index+1;
    return temp;
}
 
int main(void)
{
    #ifdef test
    freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    clock_t start=clock();
    #endif //test
 
    node beg;
    int tar;
    while(~scanf("%d%d%d%d",&beg.cap_a,&beg.cap_b,&beg.cap_c,&tar))
    {
        int f=0;
        bool flag[101][101][101];
        memset(flag,0,sizeof(flag));
        if(max(beg.cap_a,max(beg.cap_b,beg.cap_c))<tar)printf("no\n");
        else
        {
            beg.cnt_a=beg.cap_a;beg.index=0;
 
            queue<node>que;que.push(beg);
            flag[beg.cnt_a][beg.cnt_b][beg.cnt_c]=1;
 
            while(!que.empty())
            {
                node fir=que.front(),temp=fir;que.pop();
                if(temp.cnt_a==tar||temp.cnt_b==tar||temp.cnt_c==tar)
                {
                    f=1;
                    printf("yes\n%d\n",temp.index);
                    break;
                }
 
                for(int i=1;i<=3;++i)
                {
                    if(i<=2)
                    {
                        temp=pour_a2b(fir,i,i+1);
                        if(flag[temp.cnt_a][temp.cnt_b][temp.cnt_c]==0)
                            flag[temp.cnt_a][temp.cnt_b][temp.cnt_c]=1,que.push(temp);
 
                        temp=pour_b2a(fir,i+1,i);
                        if(flag[temp.cnt_a][temp.cnt_b][temp.cnt_c]==0)
                            flag[temp.cnt_a][temp.cnt_b][temp.cnt_c]=1,que.push(temp);
                    }
                    else
                    {
                        temp=pour_a2b(fir,1,3);
                        if(flag[temp.cnt_a][temp.cnt_b][temp.cnt_c]==0)
                            flag[temp.cnt_a][temp.cnt_b][temp.cnt_c]=1,que.push(temp);
 
                        temp=pour_b2a(fir,3,1);
                        if(flag[temp.cnt_a][temp.cnt_b][temp.cnt_c]==0)
                            flag[temp.cnt_a][temp.cnt_b][temp.cnt_c]=1,que.push(temp);
                    }
                }
            }
            if(!f)printf("no\n");
        }
    }
 
 
    #ifdef test
    clockid_t end=clock();
    double endtime=(double)(end-start)/CLOCKS_PER_SEC;
    printf("\n\n\n\n\n");
    cout<<"Total time:"<<endtime<<"s"<<endl;        //s为单位
    cout<<"Total time:"<<endtime*1000<<"ms"<<endl;    //ms为单位
    #endif //test
    return 0;
}

相关文章:

  • 基于 Prometheus + Grafana 监控微服务和数据库
  • 职业教育五金建设改革解析
  • C# 一文读懂委托与事件
  • Web Component 教程(二):如何有效管理和使用自定义属性
  • ✎ 一次有趣的经历
  • Cross-Silo Prototypical Calibration for Federated Learning with Non-IID Data
  • 【操作系统安全】任务6:Linux 系统文件与文件系统安全 学习指南
  • 【项目合集】基于ESP32的智能化妆柜
  • Linux进程信号(上)
  • Python第五章03:函数返回值和None类型
  • 网络编程知识预备阶段
  • 东隆科技携手PRIMES成立中国校准实验室,开启激光诊断高精度新时代
  • 【免费】2004-2017年各地级市实际利用外资数据
  • Grokking System Design 系统设计面试问题
  • 从零开始实现一个HTML5飞机大战游戏
  • java 中散列表(Hash Table)和散列集(Hash Set)是基于哈希算法实现的两种不同的数据结构
  • 【渗透测试】webpack对于渗透测试的意义
  • Linux 如何上传本地文件以及下载文件到本地命令总结
  • WSL2配置Humanoidbench问题mujoco.FatalError: OpenGL version 1.5 or higher required
  • Bash中关于制表符\t站位情况说明
  • 跳水世界杯女子单人10米台决赛,陈芋汐、全红婵包揽金银牌
  • 商务部:外贸优品中华行活动采购意向超167亿元
  • 泽连斯基:美乌矿产协议将提交乌拉达批准
  • 《水饺皇后》领跑五一档票房,《哪吒2》上座率仍居第一
  • 来上海喝云南咖啡!上海国际咖啡文化节助力咖啡产业破圈出海
  • 十四届全国人大常委会第十五次会议在京闭幕