leetcode-365——水壶问题
水壶问题
简单版本
这个问题算是水壶问题的简单版本,也是小时候竞赛中遇到过的,当时一直不知道怎么解。
偶然看到这么一个问题。其问题是,给定一个8升的满的水壶,一个5升的,一个3升的空水壶。问如何倒水可以倒出一个4升的水壶。每次只能将一个水壶倒满或者倒空。
以前一直不知道,原来这道题的核心思想就是bfs的状态表示。思路如下:
- 将8升往5升倒。
- 将8升往3升倒。
- 将5升往8升倒。
- 将5升往3升倒。
- 将3升依次类推。
然后用一个Data的struct来表示状态。同时,要注意记录每次出现的状态,当出现重复的状态就去剪枝叶。
代码
//c++ program
//design by >^.^<
//@date 2019-08-27 10:49:45
#include <iostream>
#include <queue>
#include <set>
#include <stdio.h>
// 这里是一个水壶问题的简化版本
// 就是给定三个水壶,分别是8,5,3升,8是满的,5,3是空的,
// 问如何让一个水壶装满4升。struct Data{int a;int b;int c;void output(){printf("(%d, %d, %d)", a, b, c);}bool operator<(const Data& rhs)const{if(a == rhs.a){if(b == rhs.b){return c < rhs.c;}else{return b < rhs.b;}}else{return a < rhs.a;}}
};
// 思路:用bfs的方法using namespace std;
int main()
{const int capA = 8;const int capB = 5;const int capC = 3;queue<Data> myQueue;myQueue.push(Data{8, 0, 0});set<Data> visited;visited.insert(Data{8, 0, 0});int x = visited.size();while(!myQueue.empty()){// 获得当前状态auto tmp = myQueue.front();myQueue.pop();if(tmp.a == 4 || tmp.b == 4){tmp.output();cout << endl;return 0;}// 计算下一个状态int topour = 0;set<Data> tmpSet;// a倒水给b// a只能倒这么多水topour = min(tmp.a, capB - tmp.b);auto dataA2B = Data{tmp.a-topour, tmp.b+topour, tmp.c};tmpSet.insert(dataA2B);// a倒水给ctopour = min(tmp.a, capC - tmp.c);auto dataA2C = Data{tmp.a-topour, tmp.b, tmp.c+topour};tmpSet.insert(dataA2C);// b倒水给atopour = min(tmp.b, capA - tmp.a);auto dataB2A = Data{tmp.a+topour, tmp.b-topour, tmp.c};tmpSet.insert(dataB2A);// b倒水给ctopour = min(tmp.b, capC - tmp.c);auto dataB2C = Data{tmp.a, tmp.b-topour, tmp.c+topour};tmpSet.insert(dataB2C);// c倒水给atopour = min(tmp.c, capA - tmp.a);auto dataC2A = Data{tmp.a+topour, tmp.b, tmp.c-topour};tmpSet.insert(dataC2A);// c倒水给btopour = min(tmp.c, capB - tmp.b);auto dataC2B = Data{tmp.a, tmp.b+topour, tmp.c-topour};tmpSet.insert(dataC2B);int m = tmpSet.size();for(auto eachStatus : tmpSet){if(visited.count(eachStatus) != 0){continue;}else{eachStatus.output();visited.insert(eachStatus);myQueue.push(eachStatus);}}cout << endl;}}
正常版本
有两个容量分别为 x升 和 y升 的水壶以及无限多的水。请判断能否通过使用这两个水壶,从而可以得到恰好 z升 的水?
如果可以,最后请用以上水壶中的一或两个来盛放取得的 z升 水。
你允许:
装满任意一个水壶
清空任意一个水壶
从一个水壶向另外一个水壶倒水,直到装满或者倒空
示例 1: (From the famous “Die Hard” example)
输入: x = 3, y = 5, z = 4
输出: True
思路
这里的思路其实和上面非常相似。只不过这里多了个无限大的水壶。所以多了几种状态。
- 把x水倒空。
- 把x水倒满。
- 把x水倒到y里面。
- 同理对y。
我认为这个思路要比leetcode题解上面那个要重要很多。而且算是让我对bfs有了一个很深刻的理解。
代码
class Solution {public:struct Data{int x;int y;bool operator<(const Data&rhs) const{if(x == rhs.x){return y < rhs.y;}else{return x < rhs.x;}}};bool canMeasureWater(int x, int y, int z) {if(x + y < z)return false;const int capX = x;const int capY = y;Data root{0, 0};queue<Data> myQueue;set<Data> visited;myQueue.push(root);visited.insert(root);while(!myQueue.empty()){auto temp = myQueue.front();myQueue.pop(); if(temp.x + temp.y == z)return true;// 获取下一个状态set<Data> tempSet;// x倒满tempSet.insert(Data{capX, temp.y});// y倒满tempSet.insert(Data{temp.x, capY});// x倒空tempSet.insert(Data{0, temp.y});// y倒空tempSet.insert(Data{temp.x, 0});// x倒水给yint x2y = min(temp.x, capY - temp.y); tempSet.insert(Data{temp.x - x2y, temp.y + x2y});// y倒水给xint y2x = min(temp.y, capX - temp.x);tempSet.insert(Data{temp.x + y2x, temp.y - y2x});for(auto eachStatus : tempSet){// 如果这个状态已经存在,就剪枝if(visited.count(eachStatus) != 0){continue;}else{visited.insert(eachStatus);myQueue.push(eachStatus);}}}return false;}
};
leetcode-365——水壶问题相关推荐
- Leetcode.365 水壶问题
题目链接 Leetcode.365 水壶问题 mid 题目描述 有两个水壶,容量分别为 x和 y升.水的供应是无限的.确定是否有可能使用这两个壶准确得到 z升. 如果可以得到 z升水,最后请用以上水壶 ...
- LeetCode 365. 水壶问题
365. 水壶问题 题目链接-365. 水壶问题 解题思路 裴蜀定理 裴蜀等式:若a,ba,ba,b是整数,且gcd(a,b)=dgcd(a,b)=dgcd(a,b)=d,那么对于任意的整数x,yx, ...
- LeetCode 365. 水壶问题(最大公约数)
文章目录 1. 题目 2. 最大公约数 1. 题目 有两个容量分别为 x升 和 y升 的水壶以及无限多的水.请判断能否通过使用这两个水壶,从而可以得到恰好 z升 的水? 如果可以,最后请用以上水壶中的 ...
- LeetCode —— 365. 水壶问题(Python3)
有两个容量分别为 x升 和 y升 的水壶以及无限多的水.请判断能否通过使用这两个水壶,从而可以得到恰好 z升 的水? 如果可以,最后请用以上水壶中的一或两个来盛放取得的 z升水. 你允许: 装满任意一 ...
- LeetCode 365水壶问题(python)
题目描述: 有两个容量分别为 x升 和 y升 的水壶以及无限多的水.请判断能否通过使用这两个水壶,从而可以得到恰好 z升 的水? 如果可以,最后请用以上水壶中的一或两个来盛放取得的 z升 水. 你允许 ...
- 每日一题-leetcode 365. 水壶问题
有两个水壶,容量分别为 jug1Capacity 和 jug2Capacity 升.水的供应是无限的.确定是否有可能使用这两个壶准确得到 targetCapacity 升. 如果可以得到 target ...
- Leetcode 365.水壶问题
水壶问题 有两个容量分别为 x升和 y升的水壶以及无限多的水.请判断能否通过使用这两个水壶,从而可以得到恰好 z升的水? 如果可以,最后请用以上水壶中的一或两个来盛放取得的 z升 水. 你允许: 装满 ...
- LeetCode——365.水壶问题【贝祖定理】
题解 AC-Code using PII = pair<int, int>;class Solution {public:bool canMeasureWater(int x, int y ...
- leetcode:365. 水壶问题【肥鼠定理,栈模拟dfs】
分析:数学 显然最后的z是a和b的线性组合 也就是ax + by = z也就是说z是(a,b)的倍数 那就直接用gcd就好了 加个特判 ac code class Solution:def canMe ...
- [LeetCode解题报告] 365. 水壶问题
[LeetCode解题报告] 365. 水壶问题 一. 题目 1. 题目描述 2. 原题链接 二. 解题报告 1. 思路分析 2. 复杂度分析 3. 代码实现 三. 本题小结 一. 题目 1. 题目描 ...
最新文章
- 行波和驻波动画演示gif_新技能get√ | 语文课上的笔顺动画可以这么做
- oracle 增长型分区,oracle 11g 分区表创建(自动按年分区)
- 2019手卫生定义_2021年卫生资格考试部分科目大纲和教材变化归总!
- Teiid:数据虚拟化Data Virtualization平台
- KeyMob:为国内应用开发者管理的广告聚合平台
- TensorFlow(2)-训练数据载入
- Git前世今生-版本控制软件的发展
- Java多线程-线程的生命周期
- 项目管理的49个过程整理
- excel拆分单元格内容_Excel中最神奇的一个快捷键!牛!!
- 低光照图像增强论文Low-Light Image Enhancement with Normalizing Flow阅读笔记
- tf.trian.match_filenames_once
- ansys apdl变量基本操作
- 证书类型、自签CA证书、https双向认证(一篇就懂系列)
- 顶尖量化交易公司 CEO 如何缔造量化金融王国?
- 小篮子玩意儿、你苏爷就是扣字神话不服气么。
- Nolia 给CC添加过滤器
- Android 文件打开方式
- #创新应用#全球快递追踪:五次查询只需1KB!
- stlinkv2红灯闪烁_STLINK V2安装使用详解
热门文章
- 清除数组内容函数memset函数
- 8 项 Python 基本技能
- mysql between和in_mysql between and、==、in性能实例分析
- html4可以class,class4:HTML入门.ppt
- The user specified as a definer (‘root‘@‘%‘) does not exist
- 人遛狗程序,狗在特定的时间做指定的事情
- Cerveau Technologies, Inc.与日本东京都老人综合研究所签订研究协议
- 什么是 SUSE Studio?
- 10月26日绿健简报,星期三,农历十月初二
- 集合 ListT 排重方法 Distinct()