POJ1606 Jugs

  题目大意:指定两个水杯的容量A,B和规定的目标容量N,要求通过三种操作——要么倒空,要么续满,要么从一个杯子往另一个杯子里面倒水知道一个被倒空或另一个被倒满为止。

  这道题是一个隐式图问题。可以利用BFS搜索进行解答。

  在普通的BFS求解最短路径的时候,一般会给出一个二维的数组或是直接给出一张二维的图,我们通过取当前点的邻接点的方法进行遍历。而在隐式图中,我们没有明显的图,无法通过取邻接点的方法进行操作,但是我们只要想到,其实对这两个水杯而言,改变水杯初始状态和下一个状态的只有六种操作:a杯倒空;b杯倒空;外面的水给a杯续满;b杯倒给a杯且未将a杯倒满;b杯倒给a杯且将a杯倒满;外面的水给b杯倒满;a杯倒给b杯且未将b杯倒满;a杯倒给b杯且将b杯倒满。

  显然在倒水的过程中,两个杯子的装水的状态在不断变化。所以我们可以以状态作为出发点进行遍历。当我们每次进行一次合法的操作获得一个新的状态时,就将这个状态加入队列中,然后进一步进行下一次操作。

  同普通的BFS特判相同,我们需要确定当前的新状态是新的而不是之前出现过的状态,同时为了方便后面输出倒水的过程,我们需要知道每一个状态的由来——他的上一个状态。所以我们定义一个map,map的key为当前状态,value为上一个状态,在每次放入之前判断map.find(current_state)是否已经存在了,如果存在就不加入队列。

  在进行递归输出时,最后当扫描到起始状态时,它的上一个状态是设定的特殊的(-1,-1),然后进一步递归,而当前为(-1,-1)状态时,这样的状态是找不到的(不可能水杯里的水是负的),所以此时递归结束开始回溯,但需要注意,回溯后,当前状态为初始状态,其上一状态是(-1,-1),这样调用我们设定的输出函数是不对的,因为输出函数是根据上一状态和当前状态的水的容量变化确定操作的,而此时的上一状态是非法的,输出的语句会出错,所以此时的第一遍进行的回溯不要执行。

  最终代码如下(使用G++通过)

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <queue>
#include <stdio.h>
#include <map>
using namespace std;
typedef struct water {int a, b;//记录A B两杯的水的多少bool operator<(const struct water& s) const{return a != s.a ? a < s.a : b < s.b;//为了让map类型为自定义的类类型,需要重新定义该函数}
}Water;
map<Water, Water> from;//value记录了当前状态是从什么状态来的
queue<Water>q;
void refresh(Water& s, Water& t) {//当前状态是否已经经历过if (from.find( t) == from.end()) {//当前状态是新的状态from[t] = s;//更新前驱状态//合法的状态,加入到队列中q.push(t);}
}
void PourString(Water& s, Water& t,int A,int B) {if (t.a == 0 && s.b == t.b)printf("empty A\n");else if (t.b == 0 && s.a == t.a)printf("empty B\n");else if (t.a == A && t.b == s.b)printf("fill A\n");else if (t.b == B && s.a == t.a)printf("fill B\n");else if (s.a > t.a)printf("pour A B\n");elseprintf("pour B A\n");
}
void print(Water& s,int A, int B) {if (from.find(s) == from.end()) {//到达递归终点return;}else {print(from[s], A, B);if(!(s.a==0&&s.b==0))PourString(from[s], s, A, B);}
}
void bfs(int A,int B,int N) {Water s, t;s.a = s.b = 0;//设置初始状态q.push(s);from[s] = { -1,-1 };//标记初始状态while (!q.empty()) {s = q.front(); q.pop();//特判终点if (s.a == N || s.b == N) {print(s,A,B);return;}//六种操作//倒空a杯if (s.a > 0) {t.a = 0;t.b = s.b;refresh(s, t);}//倒空b杯if (s.b > 0) {t.a = s.a;t.b = 0;refresh(s, t);}//给a杯续满if (s.a < A) {//水不是来自b杯t.a = A;t.b = s.b;refresh(s, t);if (s.b != 0) {if (s.a + s.b < A) {//水来自b杯且到不满A杯t.a = s.a + s.b;t.b = 0;refresh(s, t);}else {//来自b杯且可以倒满t.a = A;t.b = s.b - (A - s.a);refresh(s, t);}}}//给b杯续满if (s.b < B) {//水不是来自a杯t.b = B;t.a = s.a;refresh(s, t);if (s.a != 0) {if (s.a + s.b < B) {//水来自a杯且倒不满t.a = 0;t.b = s.a + s.b;refresh(s, t);}else {//水来自a杯且倒满t.b = B;t.a = s.a - (B - s.b);refresh(s, t);}}}}
}
int main(void) {int a, b, n;while (cin>>a>>b>>n) {from.clear();while (!q.empty()) q.pop();bfs(a, b, n);printf("success\n");}
}

POJ 1606 Jugs相关推荐

  1. poj 1606 Jugs(广搜BFS+路径输出)

    转载请注明出处:http://blog.csdn.net/u012860063?viewmode=contents 题目链接:http://poj.org/problem?id=1606 此题和poj ...

  2. POJ前面的题目算法思路【转】

    1000 A+B Problem 送分题 49% 2005-5-7 1001 Exponentiation 高精度 85% 2005-5-7 1002 487-3279 n/a 90% 2005-5- ...

  3. POJ 超详细分类

    POJ 各题算法 1000    A+B Problem            送分题     49%    2005-5-7 1001    Exponentiation         高精度   ...

  4. ACM题集以及各种总结大全(转)

    ACM题集以及各种总结大全! 虽然退役了,但是整理一下,供小弟小妹们以后切题方便一些,但由于近来考试太多,顾退役总结延迟一段时间再写!先写一下各种分类和题集,欢迎各位大牛路过指正. 一.ACM入门 关 ...

  5. 搜索题,留着以后慢慢刷

    转过来,留着以后慢 慢 刷555.. 简单搜索 (1)深度优先搜索 (poj2488,poj3009,poj1321) (2)广度优先搜索 (poj3278,poj1426,poj3126,poj30 ...

  6. poj1066 Jugs

    poj1066 Jugs http://poj.org/problem?id=1606 解题思路:本题可以用数学方法解得,最易理解,常规的解法是搜索.直接用接近模拟的广度优先搜索即可过. 给两个容器, ...

  7. poj题目详细分类及算法推荐题目

    DP:  1011   NTA                 简单题  1013   Great Equipment     简单题  1024   Calendar Game       简单题  ...

  8. ACM POJ 题目分类(完整整理版本)

    DP: 1011   NTA                 简单题  1013   Great Equipment     简单题  1024   Calendar Game       简单题   ...

  9. POJ ZOJ题目分类

    POJ,ZOJ题目分类(多篇整合版,分类很细致,全面) 标签: 题目分类POJ整理 2015-04-18 14:44 1672人阅读 评论(0) 收藏 举报 本文章已收录于: 分类: ACM资料(5) ...

最新文章

  1. Android训练课程(Android Training) - 高效的显示图片
  2. 弄懂CNN,然后提升准确率4.21-4.27
  3. SQL Server2008R2查询数据库的物理路径
  4. 程序员所要具备的基本素质
  5. QAbstractTableModel中的data()到底执行几遍???
  6. 阿里的下一个15年:大数据是核心
  7. iPlayer惨遭破解诅咒AKAIO作者扬言要让它支持商业游戏
  8. mui(APP)全屏展示
  9. 文件自动备份和同步bypy和syncthing
  10. Thingsboard 3.1.0 - 规则链:外部结点REST API
  11. 成功的人不是最聪明的那个人,但绝对是一个交流很棒的人
  12. Ubuntu java 环境变量
  13. 数学科普书籍介绍(一)
  14. 虚拟机VMware安装苹果系统macOS,超级详细教程,附文件下载,真教程!!
  15. css:网页引入字体@font-face以及动态加载字体
  16. Java命令简易入门-3:javac与java命令之(java与jar)
  17. oppo手机在哪看电池寿命
  18. 从GMT时间转换到当地时间(北京时间)
  19. TreeList 节点拖曳
  20. Vue 无法展示网络图片处理方案

热门文章

  1. go基础知识学习笔记-篇幅很长写的我想吐
  2. 基于Java的GUI界面+SQL Server数据库课程信息管理系统
  3. 【NOIP2006】金明的预算方案
  4. 2022-03-05 使用 putty 远程连接阿里云服务器
  5. Firefox OS开发指南
  6. mtk处理器和骁龙对比_3500元以内手机的绝杀?首款MTK 天玑1000处理器手机IQOO Z发布...
  7. 数据库基础内容(超级详细)
  8. 尝试CornerNet-Lite进行目标识别并嵌入ROS
  9. 关于Mac系统接完投影仪拔下来以后有黑框的问题解决办法
  10. 修改ua html5,html5中bootstrap表单样式文件html,兼容多种UA终端