《算法笔记》系列: 问题 E: 【宽搜入门】巧妙取量

题目来源:http://codeup.cn/problem.php?cid=100000609&pid=4

题目描述

【题目描述】 
  有三个容器,容量分别为 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
#include <iostream>
#include <cstring>
#include <fstream>
#include <string>
#include <cmath>
#include <algorithm>
#include <queue>
#include <map>

using namespace std;

struct level{
    int num[3],step;
};

int BFS(level have,level full, int k){
    int record[101][100][100]={0};
    queue<level> list;
    list.push(have);
    record[have.num[0]][have.num[1]][have.num[2]] =1;
    while(!list.empty()){
        level now=list.front();
        list.pop();
        if(now.num[0]==k || now.num[1]==k || now.num[2]==k)
            return now.step;
        for(int i=0;i<3;i++){
            for(int j=0;j<3;j++){
                level next;
                if(i==j ||
                now.num[i]==0 ||
                now.num[j]==full.num[j]) {
                    continue;
                }
                int t=now.num[i]-(full.num[j]-now.num[j]);
                if(t<0){
                    next.num[i]=0;
                    next.num[j]=now.num[j]+now.num[i];
                }
                else{
                    next.num[i]=t;
                    next.num[j]=full.num[j];
                }
                next.step=now.step+1;
                next.num[3-i-j]=now.num[3-i-j];
                if(!record[next.num[0]][next.num[1]][next.num[2]]){
                    list.push(next);
                    record[next.num[0]][next.num[1]][next.num[2]]=1;
                }
            }
        }
    }
    return -1;
}

int main()
{
    level have,full;
    int k;
    while(~scanf("%d %d %d %d",&full.num[0],&full.num[1],&full.num[2],&k)) {
        have={0};
        have.num[0] = full.num[0];
        int t = BFS(have,full,k);
        if (t < 0) {
            printf("no\n");
        } else {
            printf("yes\n%d\n", t);
        }
    }
    return 0;
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值