假设有一个池塘,里面有无穷多的水,现有2个空水壶,容积分别为5升和6升。
问题是如何只用这2个水壶从池塘里取得3升的水?
@算法设计
题目 :两个水桶打水
打水问题
假设有一个池塘,里面有无穷多的水,现有2个空水壶,容积分别为5升和6升。
问题是如何只用这2个水壶从池塘里取得3升的水?
提示:以下是本篇文章正文内容,下面案例可供参考
一、思路是什么?
两个水桶容量差值是一升。此时我们会想起来一次凑1升,但是没有第三个水桶,此时我们可以逆向思维,倒水剩3升。
好!首先我们第一次给6升的水桶接满水倒给5升的水桶中,此时6升水桶剩1升水,此时我把5升的水桶倒掉,然后六升的水桶再次倒给5升的水桶,此时5升水桶就1升水,那么6升水桶接满水再次给5升水桶倒满,此时6升水桶就有了2升水了!!!是不是有思路了?再一次循环就可以获得三升水了。
二、操作实施
既然思路通了,那么方法事件有很多种,想怎么实现就怎么实现。
这里我使用栈来模仿水桶(因为倒水和装水和栈有点像嘛!哈哈)
1.使用java写吧,简单点
代码如下(示例):
//首先定义两个水桶
public static Stack<Integer> five=new Stack<>();
public static Stack<Integer> six=new Stack<>();
// 然后规定两个水桶的容量
private static final int FIVE_COUNT=5;
private static final int SIX_COUNT=6;
2.首先按照思路 要有装水的方法
代码如下(示例):
//给水桶接满水
public static void setFillWriter(Stack<Integer> bucket,int L){
while (bucket.size()<L){ //还能装就继续装
// 压入的数组表示现在有多少水
//这里你存什么都行,我只是想压入栈的顺序和水桶的现有升数一样而已。
bucket.push(bucket.size()+1);
}
}
3.然后水桶之间倒水的方法
代码如下(示例):
/***
* 老水桶往新水桶转移水
* @param oldBucket 老水桶
* @param newBucket 新水桶
* @param L 新水桶容量
*/
public static void Pourwater(Stack<Integer> oldBucket,Stack<Integer> newBucket,int L){
while (newBucket.size()<L && !oldBucket.empty()){
//新桶没装满或者老桶没倒完。
oldBucket.pop();
//这里你存什么都行,我只是想压入栈的顺序和水桶的现有升数一样而已。
newBucket.push(newBucket.size());
}
}
3.最后就是把水全倒掉的方法(就是清空了哈哈):
代码如下(示例):
/***
* 清空水桶的水
* @param bucket
*/
public static void emptyWater(Stack<Integer> bucket){
while (!bucket.empty()){
bucket.pop();
}
}
那么方法都写完了,来回倒水就行了
代码如下(示例):
public static void main(String[] args) {
System.out.printf("刚开始水桶的水水是多少?5号水桶%dL,6号水桶%dL\n",five.size(),six.size());
while (six.size()!=3){
//这个执行顺序的话最后水留在了6升的水桶里,如果把第一句放到最后,那就是水最后留在了5升的水桶里,都一样的
Pourwater(six,five,FIVE_COUNT); //6升给5升水桶倒满
setFillWriter(six,SIX_COUNT); //6升水桶加满
Pourwater(six,five,FIVE_COUNT); //6升给5升水桶倒满
emptyWater(five);//5升水桶倒掉
}
System.out.println("现在6升水桶的水是多少?"+six.peek()+"L");
//这里我用的six.peek()是因为我存的数和压入栈的顺序是一样的
//其实直接.size()就行了,我想着既然存的值就是现有的升数,不得用用嘛 hhh
}
运行结果
总结
主要的是思路而已。BYE-BYE.