用欧几里得算法解决倒水问题
2013-12-04 16:38
344 查看
庞果编程大赛的题目
有两个容器,容积分别为A升和B升,有无限多的水,现在需要C升水。
我们还有一个足够大的水缸,足够容纳C升水。起初它是空的,我们只能往水缸里倒入水,而不能倒出。
可以进行的操作是:
把一个容器灌满;
把一个容器清空(容器里剩余的水全部倒掉,或者倒入水缸);
用一个容器的水倒入另外一个容器,直到倒出水的容器空或者倒入水的容器满。
问是否能够通过有限次操作,使得水缸最后恰好有C升水。
输入:三个整数A, B, C,其中 0 < A , B, C <= 1000000000
输出:0或1,表示能否达到要求。
这种倒水问题肯定不是第一次碰到,这次碰到了,一定要弄出个究竟!
首先我想到的是方程Ax+By=C,A、B、C均为整数,有没有x,y的整数解的模型。
结果意外发现了欧几里得算法早就运用于解决此类问题了。
欧几里得算法的目的是计算两个正整数A、B的最大公约数,计算过程可以描述为:
1、计算res=A%B,A对B取余;
2、若res为0,则最大公约数为B;
3、若res不为0,则进行赋值A=B,B=res,继续第一步。
计算过程清晰了,相应的函数写法也很明显了,我想到了主要是两种方式:
1、直接循环
int res(int a,int b)
{
while(res=a%b)
{
a=b;
b=res;
}
return b;
}
退出循环后的b值即是所求的最大公约数。
2、递归写法
int res(int a,int b)
{
return b?res(a,a%b):a;
}
有一次感受到了不理解、不会用递归就注定得多敲键盘的道理啊。
说了欧几里得算法,我们重归正题,求出了A和B的最大公约数之后,怎么判断倒水是否能成功呢?
很简单,如果C能被最大公约数整除,则有办法可以倒水成功;否则就没有办法。
以下是编程挑战赛上我的代码
#include <stdio.h>
int can(int a,int b,int c) {
int res;
while(res=a%b)
{
a=b;
b=res;
}
printf("%d\n",b);
if(c%b==0)
return 1;
else
return 0;
}
//start 提示:自动阅卷起始唯一标识,请勿删除或增加。
int main()
{
printf("%d",can(4,6,7));
}
//end //提示:自动阅卷结束唯一标识,请勿删除或增加。
总得来说,虽然这个题目不是很难,但是有助于对于这一类问题的解决,谨以此文加深点印象。
有两个容器,容积分别为A升和B升,有无限多的水,现在需要C升水。
我们还有一个足够大的水缸,足够容纳C升水。起初它是空的,我们只能往水缸里倒入水,而不能倒出。
可以进行的操作是:
把一个容器灌满;
把一个容器清空(容器里剩余的水全部倒掉,或者倒入水缸);
用一个容器的水倒入另外一个容器,直到倒出水的容器空或者倒入水的容器满。
问是否能够通过有限次操作,使得水缸最后恰好有C升水。
输入:三个整数A, B, C,其中 0 < A , B, C <= 1000000000
输出:0或1,表示能否达到要求。
这种倒水问题肯定不是第一次碰到,这次碰到了,一定要弄出个究竟!
首先我想到的是方程Ax+By=C,A、B、C均为整数,有没有x,y的整数解的模型。
结果意外发现了欧几里得算法早就运用于解决此类问题了。
欧几里得算法的目的是计算两个正整数A、B的最大公约数,计算过程可以描述为:
1、计算res=A%B,A对B取余;
2、若res为0,则最大公约数为B;
3、若res不为0,则进行赋值A=B,B=res,继续第一步。
计算过程清晰了,相应的函数写法也很明显了,我想到了主要是两种方式:
1、直接循环
int res(int a,int b)
{
while(res=a%b)
{
a=b;
b=res;
}
return b;
}
退出循环后的b值即是所求的最大公约数。
2、递归写法
int res(int a,int b)
{
return b?res(a,a%b):a;
}
有一次感受到了不理解、不会用递归就注定得多敲键盘的道理啊。
说了欧几里得算法,我们重归正题,求出了A和B的最大公约数之后,怎么判断倒水是否能成功呢?
很简单,如果C能被最大公约数整除,则有办法可以倒水成功;否则就没有办法。
以下是编程挑战赛上我的代码
#include <stdio.h>
int can(int a,int b,int c) {
int res;
while(res=a%b)
{
a=b;
b=res;
}
printf("%d\n",b);
if(c%b==0)
return 1;
else
return 0;
}
//start 提示:自动阅卷起始唯一标识,请勿删除或增加。
int main()
{
printf("%d",can(4,6,7));
}
//end //提示:自动阅卷结束唯一标识,请勿删除或增加。
总得来说,虽然这个题目不是很难,但是有助于对于这一类问题的解决,谨以此文加深点印象。
相关文章推荐
- 241-字母统计
- myeclipse配置hadoop开发环境
- 《REWORK》启示录 招聘笔杆子——程序员为什么值得写博客
- 数据结构图之二(最小生成树--克鲁斯卡尔算法)
- 二叉搜索树 C语言实现
- win7系统自带防火墙使用技巧解读
- 中国汽车品牌口碑榜之:--2013年第3季度福州跑车综合口碑排名
- 生成get方法和set方法,toString方法
- nginx绑定多个域名
- 数组的选择排序法。
- arch与gentoo对比
- IOS中输入框被软键盘遮挡的解决办法
- access数据库密码的mdb的访问报错“无法启动应用程序,或是已被其他用户已独占方式打开”
- ☀【移动】隐藏地址栏
- 网站变灰代码
- 如何使用outlook rxpress 收发邮件
- 蓝牙(Bluetooth)---源码目录及设置应用源码分析
- qsort用法总结
- opencv中用Resize和图像金字塔改变尺寸的区别
- 坚持学习法的路线