蓝桥杯软件大赛---分红酒(广度优先搜索)
题目:
标题:分红酒
有4个红酒瓶子,它们的容量分别是:9升, 7升, 4升, 2升
开始的状态是 [9,0,0,0],也就是说:第一个瓶子满着,其它的都空着。
允许把酒从一个瓶子倒入另一个瓶子,但只能把一个瓶子倒满或把一个瓶子倒空,不能有中间状态。这样的一次倒酒动作称为1次操作。
假设瓶子的容量和初始状态不变,对于给定的目标状态,至少需要多少次操作才能实现?
本题就是要求你编程实现最小操作次数的计算。
输入:最终状态(逗号分隔)
输出:最小操作次数(如无法实现,则输出-1)
例如:
输入:
9,0,0,0
应该输出:
0
输入:
6,0,0,3
应该输出:
-1
输入:
7,2,0,0
应该输出:
2
分析:
对于状态的理解,对于学习算法是非常重要的,尤其是对于搜索的算法和动态规划的算法。我们可以把四个瓶子里面的水的体积抽象成一种状态(a, b, c, d),然后状态转移无非就是a->b, b->a, c-> a, a->c, b->c, c->b, d->a, a->d, d->c, c->d, b->d, d->b共A(4,2) = 3 * 4 = 12种。当然其中有一些操作是无效的,比如a为空,a就不可以倒给其他瓶子了。a要是满,其他瓶子也不能倒给a。
状态定义好了,状态转移的操作也理清了,下一步就是爆搜了。由于这里要的是最少的操作,那就用广度优先搜索。
为了提高搜索的效率,防止一个状态被搜索到多次,我们用一个hash (哈希)标志 状态是否被搜到过。
为了代码编起来简洁一些,我们定义一个数组bot[4]存储每个瓶子里面的酒的体积。 具体见代码。
算法框架:
1、用一个数组end[4]记录目标状态,并输入状态
2、用一个数组cap[4]记录每个瓶子的最大容量
3、将初始状态放入队列
4、从队列中取出队头的状态
5、判断是否是目标状态,是的话直接输入到达该状态需要多少步,算法结束
6、执行12中可能的操作,当然其中有一些不可行,得到操作后的状态,放入队列
7、重复4、5、6直到队列为空,则输出-1,否则必从5输出了结果
代码:
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<queue>
using namespace std;
struct State
{int bot[4], step;
};
int cap[5] = {9, 7, 4, 2};
bool vis[10][8][5][3];
bool pour(State& tmp, int i, int j)
{if(tmp.bot[i] == 0) return false;if(tmp.bot[j] == cap[j]) return false;if(tmp.bot[i] + tmp.bot[j] <= cap[j]){tmp.bot[j] = tmp.bot[i] + tmp.bot[j];tmp.bot[i] = 0;}else{tmp.bot[i] -= (cap[j] - tmp.bot[j]);tmp.bot[j] = cap[j];}if(vis[tmp.bot[0]][tmp.bot[1]][tmp.bot[2]][tmp.bot[3]]){return false;}else{vis[tmp.bot[0]][tmp.bot[1]][tmp.bot[2]][tmp.bot[3]] = 1;}tmp.step ++;return true;
}
int main(void)
{memset(vis, 0, sizeof(vis));int end[5];for(int i = 0; i < 4; i ++)scanf("%d", &end[i]);queue<State> q;q.push((State){{9, 0, 0, 0},0});bool flag = false;while(!q.empty()){State tmp = q.front();q.pop();int i;for(i = 0; i < 4; i ++){if(tmp.bot[i] != end[i])break;}if(i == 4){flag = true;printf("%d\n", tmp.step);break;}for(int i = 0; i < 4; i ++){for(int j = 0; j < 4; j ++)if(i != j){State tmp2 = tmp;if(pour(tmp2, i, j)){q.push(tmp2);}}}}if(!flag)printf("-1\n");return 0;
}
蓝桥杯软件大赛---分红酒(广度优先搜索)相关推荐
- 蓝桥杯计算机软件大赛什么时间,蓝桥杯软件大赛培训总结
<蓝桥杯软件大赛培训总结>由会员分享,可在线阅读,更多相关<蓝桥杯软件大赛培训总结(5页珍藏版)>请在人人文库网上搜索. 1.蓝桥杯软件大赛培训总结"蓝桥杯" ...
- 2013年蓝桥杯软件大赛预赛java本科b组答案_2013年蓝桥杯软件大赛预赛C本科B组试题...
第四届"蓝桥杯"全国软件专业人才设计与创业大赛选拔赛结果题目标题: 高斯日记 大数学家高斯有个好习惯:无论如何都要记日记. 他的日记有个与众不同的地方,他从不注明年月日,而是用一个 ...
- “蓝桥杯”软件大赛入门训练4道题
问题描述 Fibonacci数列的递推公式为:Fn=Fn-1+Fn-2,其中F1=F2=1. 当n比较大时,Fn也非常大,现在我们想知道,Fn除以10007的余数是多少. 输入格式 输入包含一个整数n ...
- 金蝉素数c语言,算法笔记_204:第四届蓝桥杯软件类决赛真题(Java语言C组)
前言:以下代码仅供参考,若有错误欢迎指正哦~ 1好好学习 汤姆跟爷爷来中国旅游.一天,他帮助中国的小朋友贴标语.他负责贴的标语是分别写在四块红纸上的四个大字:"好.好.学.习".但 ...
- 2021年第十二届蓝桥杯软件类省赛python组试题及其解析。
目录 一.卡片 二.直线 三.货物摆放 四.路径 五.回路计算 六.时间显示 七.杨辉三角 八.左孩子右兄弟 九.异或数列 十.括号序列 一.卡片 本题总分:5分 [问题描述] 小蓝有很多数字卡片,每 ...
- 蓝桥杯软件组如何混进省一
0.蓝桥杯介绍 为促进软件和信息领域专业技术人才培养,提升高校毕业生的就业竞争力,由教育部就业指导中心支持,工业和信息化部人才交流中心举办蓝桥杯大赛.十一年来,包括北大.清华在内的超过 1300 余所 ...
- java发现杯_达内第二届发现杯软件大赛(JAVA A卷)试题.docx
达内第二届发现杯软件大赛(JAVA A卷)试题 达内"发现杯"软件大赛 Java?(100分制,考试时间180分钟)一.单选题(10小题共20.0分)1.?下列Java代码的正确输 ...
- 2021年第十二届蓝桥杯软件类省赛python组
目录 2021年第十二届蓝桥杯软件类省赛python组 1.卡片 常规做法 使用functions.Counter计数 2.直线 3.货物摆放 4.路径 5.回路计算 递归--太慢跑不出来 状态压缩D ...
- 蓝桥杯评分标准_第十届蓝桥杯软件个人赛校内选拔赛评分标准和选拔标准.doc...
第十届"蓝桥杯"软件个人赛校内选拔赛评分标准和选拔标准 一.竞赛规则 1. 本次"蓝桥杯"校内选拔赛比赛平台: HYPERLINK "" . ...
最新文章
- 中文金额大写转换处理
- 转载别人的转载 Android Studio实用插件集合
- PHP CRC16 校验码的算法怎么使用
- Matlab | MATLAB编辑器:无法使用GBK编码保存文件,请改用UTF-8编码保存文件(问题解决)
- MATLAB数据分析3
- 【Java】浅析Math类
- mysql 数据库乱码_Mysql数据库乱码问题的对应方式
- 20200329:K 个一组翻转链表(leetcode25)
- 《神经网络和深度学习》系列文章七:实现我们的神经网络来分类数字(上)...
- 英语四级高频词汇电子版_英语四级使用频率最高的580个词汇
- android 打地鼠,Android实现打地鼠小游戏
- [硬件选型] 工业相机之参数和选型
- 无论用手工处理还是用计算机进行处理,会计电算化试卷
- windows mingw 64,SDL ,devil,glfw,opengl,qt环境搭建
- android 定制ROM集成 YouTube API,并实现双屏异显(主屏展示列表,副屛播放视频)
- 看了本文让你laravel安装laravel-queue-rabbitmq一路顺风
- 电子护照阅读器解决方案
- hhkb适合写java吗_起底这届HHKB最强新品键盘,究竟好在哪儿?
- Xposed模块 -- Hook函数参数
- HTML插入空格 HTML多个空格 HTML实体
热门文章
- 汇编实验之用debug命令查看寄存器和内存中的内容
- 狂神说笔记——SpringBoot操作数据库22-5
- MFC动态建立二叉树、序列检错以及获取父节点
- 并发环境下hashmap头插法的问题
- 怎么用计算机做手工,在电脑上做手工的好帮手—小青蛙3D折纸工具
- Activiti系列(一)画流程图
- exception in thread “main” org.apache.hadoop.hadooplllcgalargumentException:Ha is not enabled for
- python定时器爬取豆瓣音乐Top榜歌名
- python随机模块random的22种函数
- Zookeeper 分布式锁