经典问题----倒水(详细解析)
来源:互联网 发布:java在线考试系统源码 编辑:程序博客网 时间:2024/05/16 19:01
倒水问题解析
有两个容器,容积分别为A升和B升,有无限多的水,现在需要C升水。 我们还有一个足够大的水缸,足够容纳C升水。起初它是空的,我们只能往水缸里倒入水,而不能倒出。 可以进行的操作是: 把一个容器灌满; 把一个容器清空(容器里剩余的水全部倒掉,或者倒入水缸); 用一个容器的水倒入另外一个容器,直到倒出水的容器空或者倒入水的容器满。 问是否能够通过有限次操作,使得水缸最后恰好有C升水。
输入:三个整数A, B, C,其中 0 < A , B, C <= 1000000000
输出:0或1,表示能否达到要求。
函数头部:
c语言:1表示可以,0表示不可以 int can(int a,int b,int c);
c++语言: true表示可以,false表示不可以 bool can(int a,int b,int c);
java语言:true表示可以,false表示不可以 public class Main {public static boolean can(int a,int b,int c); }
分析
经典的倒水问题,有不少公司也出了类似的面试题目,有的以选择题形式出现,也有编程题形式出现的,下面做简要的分析:
对题目做简要的处理分析后,C升水是可以分多次倒入的,假设A > B,那么每次可以倒的水的量为A , B , (A + B) ,( A - B)升水,设置4个因子,分别为x1 , x2, x3, x4 , (x1 , x2, x3, x4 属于整数),如果可以使得水缸最后恰好有C升水,那么必然存在整数x1 , x2, x3, x4,使得
Ax1 + Bx2, + (A + B)x3 + (A - B)x4 = C 等式成立;
对等式做一定的变换,得到公式
(x1 + x3 + x4)A + (x2 + x3 - x4)B = C ; --( 1-1 )
设 x = x1 + x3 + x4 , y = x2 + x3 - x4 , x, y 均为整数;最终得到公式
xA + yB = C ; --( 1-2 )
x1 , x2, x3, x4可以假设为正整数,用几个for循环可以实现,但是时间复杂度太大,为O(N4),题目中给的范围是0 < A , B, C <= 1000000000;整数在十亿范围,显然运行时间肯定会超过3s ,不符合要求,那有没有更加合适的方法呢,在算法的书里面,有一个算法,与公式( 1-2 ) 不谋而合,是扩展的欧几里德算法,算法描述:
定理:
对于不完全为 0 的非负整数 a,b,gcd(a,b)表示 a,b 的最大公约数,必然存在整数对 x,y ,使得 gcd(a,b)=ax+by. 根据欧几里德扩展算法,Gcd(A, B) = Ax + By,求出A和B的最大公约数,如果C能被最大公约数整除Gcd(A, B) 整除,那就可以实现水缸里恰好为C升水; 那题目就直接转换为求A 、B的最大公约数了,求公约数可以用辗转相除法,代码如下:int mod(int a, int b) { return b ? mod(b, a%b) : a; } bool can (int a, int b, int c){ int res; res=mod(a, b); if (0 == c % res) return true; else return false;}
同样,附带几个测试用例:
输入:A = 1234567, B = 7654321 , C = 9999999, 输出:result = 1;
输入:A = 9999, B = 5555, C = 2222, 输出:result = 1;
输入:A = 1000000000, B = 2, C = 1 , 输出:result = 0.
下面是做一个实例演示:假设A = 11 , B =39 , C = 2,返回值为1,说明可以实现,为方便叙述,采用A(11) , B(39)表示容器,步骤如下:
1、 将容器 B(39) 倒满水,然后3次倒入 A(11) 容器中,那么 B(39) 剩下 39 - 11 * 3 = 6升水,此时A(11)可用;
2、 把 B(39) 中的 6 升水全部倒入容器 A(11) 中,那么容器 A(11) 中有 6 升水,5 升是空的,此时B(39)可用;
3、 把 B(39) 倒满水,然后往第2步得到的 A(11 )倒入直到 A(11) 满为止,那B(39)剩下39 - 5 = 34 升水,清空 A(11) ,此时A(11)可用;
4、 步骤3得到的 B(39) 容器有34升水,3次倒入 A(11)中,那 B(39)中剩下 34 - 11 * 3= 1升水,此时 A(11)可用;
5、 把步骤4的 1 升水倒入水缸,清空 A(11) 和 B(39),重做步骤1 - 4,再往水缸倒入1升水,那水缸里就是 1 + 1 = 2 升水了。
原文链接:http://www.th7.cn/Program/c/201309/148378.shtml
- 经典问题----倒水(详细解析)
- 入门经典-p130-倒水问题代码解析
- UVA 571 Jugs(经典倒水问题)
- 倒水问题 算法入门经典
- UVA - 571 - Jugs (数论 - 经典倒水问题)
- 倒水问题(智力)
- 《算法竞赛入门经典》 7.5 倒水问题
- (转载)BFS 倒水问题 HDU 1495倒水问题
- 倒水问题(算法挑战)
- 倒水问题题解(勿喷)
- USACO 1.4 Mother's Milk 母亲的牛奶(经典的dfs倒水问题)
- 倒水问题
- 倒水问题
- 倒水问题
- 倒水问题
- 倒水问题
- 倒水问题
- 倒水问题
- MyEclipse破解
- 把cocos2dx的游戏打包成dylib,实现动态更新
- 影片介绍
- Apache 是如何完成负载均衡策略配置
- java程序中调用摄像头实现jsp程序摄像头数据采集
- 经典问题----倒水(详细解析)
- 小我站长对站点美化总结:哥做的不是优化是流量
- java 中调用c++Dll的路径问题
- 浅析小我私家对内链的需要性的一些意见
- mongodb集群AB复制 安装与配置
- 转‘OpenGl鼠标控制摄像机camera实现三维漫游
- iOS开发 真机调试 芳仔小脚丫
- 真机打包ipa程序
- 工作四年总结