分红酒(广度优先搜索)
标题:分红酒
有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
最初做这道题的时候,并没有任何思路。
最近准备软件大赛的时候,刚好看到这题,我便开始用刚学会的深搜来解决,结果发现不太实际,自己的代码也没有通过。
后来听同学说,遇到这种求最小次数等的问题最好用广搜,所以便开始学习广搜,结果如此奇妙,果然还是广搜的效率高很多。
通过学习大牛的思路,终于理解了这道题,通过我自己的代码和注释,希望对别人有所帮助。
1 #include<iostream> 2 #include<queue> 3 using namespace std; 4 5 typedef struct 6 { 7 int now[4]; 8 int step; 9 }state; 10 int full[4] = {9 , 7 , 4 , 2}; 11 int vis[10][8][5][3]; //用来判断是否是已经记录的状态 12 13 int bfs(state& temp , int i , int j) 14 { 15 if(i == j) return 0; //i中的水不能倒在i中 16 if(temp.now[i] == 0) return 0; //i中没有水,不能操作 17 if(temp.now[j] == full[j]) return 0; //j中水已满,不能操作 18 if(temp.now[i] + temp.now[j] <= full[j]) //进入倒水环节 19 { 20 temp.now[j] = temp.now[j] + temp.now[i]; //将i中的水全部倒入j中 ****** 21 temp.now[i] = 0; 22 } 23 else //将j倒满 24 { 25 temp.now[i] = temp.now[i] - (full[j] - temp.now[j]); 26 temp.now[j] = full[j]; 27 } 28 if(vis[temp.now[0]][temp.now[1]][temp.now[2]][temp.now[3]]) 29 {return 0;} 30 else vis[temp.now[0]][temp.now[1]][temp.now[2]][temp.now[3]] = 1; 31 temp.step++; 32 return 1; 33 } 34 int main() 35 { 36 int end[4]; //需要输入的最后状态 37 int i , j , flag; 38 while(cin>>end[0]>>end[1]>>end[2]>>end[3]) 39 { 40 queue<state>q; 41 flag = 0; 42 memset(vis , 0 , sizeof(vis)); 43 if(end[0]+end[1]+end[2]+end[3]!=9) //非法状态 44 {cout<<"-1"<<endl;flag = 1;} 45 if(end[0]>full[0]||end[1]>full[1]||end[2]>full[2]||end[3]>full[3]) 46 {cout<<"-1"<<endl;flag = 1;} //非法状态 47 state star; //初始状态 初始化 48 star.now[0] = 9; 49 star.now[1] = 0; 50 star.now[2] = 0; 51 star.now[3] = 0; 52 star.step = 0; 53 q.push(star); //将初始状态压入队列 54 while(!q.empty()) 55 { 56 state temp = q.front(); 57 q.pop(); 58 if(temp.now[0]==end[0]&&temp.now[1]==end[1]&&temp.now[2]==end[2]&&temp.now[3]==end[3]) 59 { 60 flag = 1; 61 printf("%d\n" , temp.step); 62 break; 63 } 64 for(i = 0; i < 4; i++) 65 { 66 for(j = 0; j < 4; j++) 67 { 68 state temp2 = temp; 69 if(bfs(temp2 , i , j)) 70 q.push(temp2); 71 } 72 } 73 } 74 if(!flag) cout<<"-1"<<endl; 75 } 76 return 0; 77 }
转载于:https://www.cnblogs.com/nigel-jw/archive/2013/05/06/3063659.html
分红酒(广度优先搜索)相关推荐
- JAVA广度优先搜索---寻找从A点到B点最短路径
前言 搜索界两大基础搜索算法分别是广度优先搜索和深度优先搜索. 搜索算法可以用于寻找图的连通性. 一个普通的二维地图,从A点到B点,有两个问题. 能否到达? 怎样以最短的路径走到B点? 这是搜索算法能 ...
- 蓝桥杯软件大赛---分红酒(广度优先搜索)
题目: 标题:分红酒 有4个红酒瓶子,它们的容量分别是:9升, 7升, 4升, 2升 开始的状态是 [9,0,0,0],也就是说:第一个瓶子满着,其它的都空着. 允许把酒从一个瓶子倒入另一 ...
- PTA:7-102 喊山 (30分)---解析(bfs广度优先搜索,vector)
7-102 喊山 (30分) 喊山,是人双手围在嘴边成喇叭状,对着远方高山发出"喂-喂喂-喂喂喂--"的呼唤.呼唤声通过空气的传递,回荡于深谷之间,传送到人们耳中,发出约定俗成的& ...
- 深度优先搜索和广度优先搜索的比较与分析
一)深度优先搜索的特点是: (1)无论问题的内容和性质以及求解要求如何不同,它们的程序结构都是相同的,即都是深度优先算法(一)和深度优先算法(二)中描述的算法结构,不相同的仅仅是存储结点数据结构和产生 ...
- Java实现算法导论中图的广度优先搜索(BFS)和深度优先搜索(DFS)
对算法导论中图的广度优先搜索(BFS)和深度优先搜索(DFS)用Java实现其中的伪代码算法,案例也采用算法导论中的图. import java.util.ArrayList; import java ...
- LQ训练营(C++)学习笔记_广度优先搜索
这里写目录标题 四.广度优先搜索 1.队列的概念 2.小朋友报数问题 2.1 问题描述 2.2 代码实现 3.广度优先搜索概念 4.走迷宫问题 4.1 问题描述 4.2 代码实现 5.过河卒问题 5. ...
- 31 | 深度和广度优先搜索:如何找出社交网络中的三度好友关系?
问题导入 给你一个用户,如何找出这个用户的所有三度(其中包含一度.二度和三度)好友关系? 搜索算法 算法是作用于具体数据结构之上的,深度优先搜索算法和广度优先搜索算法都是基于"图" ...
- Leetcode广度优先搜索笔记2 腐烂的橘子
994. 腐烂的橘子:带有变量控制的矩阵中的广度优先搜索 在给定的 m x n 网格 grid 中,每个单元格可以有以下三个值之一: 值 0 代表空单元格: 值 1 代表新鲜橘子: 值 2 代表腐烂的 ...
- 广度优先搜索(BFS)最短路径输出表示(三种方法)
相信我,看完之后,你会对BFS有种全新的了解,彻底掌握BFS 只需要这一篇就足够啦,狗头 BFS路径表示 广度优先搜索顾名思义就是以迷宫里的无向图某一个点,借助队列,一层一层以该点为中心散开进行搜索, ...
最新文章
- JAVA-JSP Scriptlets(JSP小脚本)
- oc 计算 带括号 式子
- SLAM: 图像角点检测的Fast算法(OpenCV文档)
- Git 分支管理 Feature分支 强行删除分支
- c语言函数编写格式,在c语言中如何实现函数模板?
- .net mysql limit 分页原理_浅谈MySQL分页Limit的性能问题
- bzoj 1619: [Usaco2008 Nov]Guarding the Farm 保卫牧场(DFS)
- 深度神经网络的正则化
- [转]Android TV 遥控器适配
- 如何开启远程桌面的服务器,如何启用远程服务器 开启服务器的远程桌面控制...
- Android 清理app缓存数据的方法
- 苹果计算机远程桌面连接,远程桌面连接mac,小编教你苹果mac如何远程桌面连接...
- C++ 使用fdk-aac对音频编码
- oom killer 详解
- win10系统的字体突然变成繁体字,如何修改回简体中文
- 寒冬之下持续吸金,蛰伏30年的国产数据库终迎黄金时代?
- ViewFlipper和ViewPager
- 约瑟夫环c语言单链表的解题思路,太透彻了:约瑟夫环的三种解法
- JPO 创建Excel相关问题解决
- 谷歌研发智能隐形眼镜