蓝桥杯:核桃的数量

来源:互联网 发布:蜘蛛侠归来 知乎 编辑:程序博客网 时间:2024/04/20 12:03
  历届试题 核桃的数量  
时间限制:1.0s   内存限制:256.0MB
问题描述

小张是软件项目经理,他带领3个开发组。工期紧,今天都在加班呢。为鼓舞士气,小张打算给每个组发一袋核桃(据传言能补脑)。他的要求是:

1. 各组的核桃数量必须相同

2. 各组内必须能平分核桃(当然是不能打碎的)

3. 尽量提供满足1,2条件的最小数量(节约闹革命嘛)

输入格式
输入包含三个正整数a, b, c,表示每个组正在加班的人数,用空格分开(a,b,c<30)
输出格式
输出一个正整数,表示每袋核桃的数量。
样例输入1
2 4 5
样例输出1
20
样例输入2
3 1 1
样例输出2
3

题目分析:

核桃数量此题,就是求三个数的最小公倍数。而想要求出最小公倍数,我们需要先求出两个数的最小公倍数;

而要求得两个数的最小公倍数,我们又要先求出其最大公约数。那么我们先求两个数的最大公约数。

最大公约数,我们一般是用辗转相除法来求得。

何为辗转相除法?

假设我们有两个数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);

好了,现在最大公约数已经求出来了。

下面我们来看一张图,怎样求三个数的最小公倍数。

以2,4,5三个数为例:


从上图可以看出,我们平时计算都是用下面的那种方法。但是计算机它不会这样计算,必须一步一步来。

上图中的①②步骤,是我们为计算机设计的计算方案,具体程序实现见附录。

附录:

/*Name: 蓝桥杯:核桃的数量 Copyright: 供交流 Author: JopusDate: 06/02/14 10:00Description: 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使用 
内存使用 
评测详情62666Jopus核桃的数量02-07 16:291.254KBC正确1000ms784.0KB评测详情


转载请保留原文地址:http://blog.csdn.net/jopus/article/details/18971035

0 0