小张是软件项目经理,他带领3个开发组。工期紧,今天都在加班呢。为鼓舞士气,小张打算给每个组发一袋核桃(据传言能补脑)。他的要求是:
1. 各组的核桃数量必须相同
2. 各组内必须能平分核桃(当然是不能打碎的)
3. 尽量提供满足1,2条件的最小数量(节约闹革命嘛)
题目分析:
核桃数量此题,就是求三个数的最小公倍数。而想要求出最小公倍数,我们需要先求出两个数的最小公倍数;
而要求得两个数的最小公倍数,我们又要先求出其最大公约数。那么我们先求两个数的最大公约数。
最大公约数,我们一般是用辗转相除法来求得。
何为辗转相除法?
假设我们有两个数9,21,现在我们求9,21的最大公约数:
21 % 9 = 3
9 % 3 = 0
那么,3就是9,21的最大公约数。
现在我们抽象化一下:假设我们有两个数a,b(a<b),现在我们求a,b的最大公约数:
先利用辗转相除法写出算法(如下):
较大数b = 较小数(上一轮)
较小数a = 余数(上一轮)
模仿上面,我们需要借助一个临时变量,可以得出如下:
while (b%a != 0)
{
t = b % a;
b = a;
a = t;
}
printf("最大公约数:%d",b);
好了,现在最大公约数已经求出来了。
下面我们来看一张图,怎样求三个数的最小公倍数。
从上图可以看出,我们平时计算都是用下面的那种方法。但是计算机它不会这样计算,必须一步一步来。
上图中的①②步骤,是我们为计算机设计的计算方案,具体程序实现见附录。
附录:
/*
Name: 蓝桥杯:核桃的数量
Copyright: 供交流
Author: Jopus
Date: 06/02/14 10:00
Description: dev-cpp 5.5.3
*/
#include <stdio.h>
//思路:核桃数量,即求三个数的最小公倍数
//返回a,b两数的最大公约数
int gcd(int a, int b)
{
return a%b == 0?b:gcd(b,a%b);
}
//主函数
int main()
{
int a = 0, b = 0, c = 0, ab = 0;
scanf("%d%d%d",&a,&b,&c);
ab = a*b/gcd(a,b); //得到a,b两数的最小公倍数
printf("%d",ab*c/gcd(ab,c)); //得到ab,c两数的最小公倍数(即核桃数量)
return 0;
}
附录1:返回两数最大公约数(非递归版)
int gcd(int a, int b)
{
int t = 0;
while (a%b != 0) //辗转相除法(结束标志)
{
t = a%b;
a = b; //a存放a,b中较小数(b如果传递进来时非较小数,辗转一次将自动变为最小数:因为a%b<b)
b = t; //b存放a,b的余数
}
return b;
}
附录2: 返回两数最大公约数(递归版:分析)
int gcd(int a, int b)
{
if (a%b == 0) //递归出口:参见(辗转相除法)
return b; //返回较小值
else
return gcd(b,a%b);//(b为a,b中较小数)b如果传递进来时非较小数,辗转一次将自动变为最小数
}
参考文献:
百度百科,最大公约数,http://baike.baidu.com/view/47637.htm,2014年2月9日
提交序号 | 姓名 | 试题名称 | 提交时间 | 代码长度 | | | | CPU使用 | 内存使用 | 评测详情 |
---|---|---|---|---|---|---|---|---|---|---|
62666 | Jopus | 核桃的数量 | 02-07 16:29 | 1.254KB | C | 正确 | 100 | 0ms | 784.0KB | 评测详情 |
转载请保留原文地址:http://blog.csdn.net/jopus/article/details/18971035