Problem 1:
If we list all the natural numbers below 10 that are multiples of 3 or 5,we get 3,5,6 and 9.The sum of these multiples is 23.
Find the sum of all the multiples of 3 or 5 below 1000.
问题1:
如果我们列出小于10的3或5的倍数则有3,5,6,9。它们的和为23。
找出小于1000的3或5的所有倍数的和。
分析:
思路1:将小于1000的所有3的倍数相加,再加上所有5的倍数(且不是3的倍数)。
思路2:3的倍数组成一等差数列,5的倍数也组成等差数列,将这两个等差数列相加再减去重复加过的数字(3,5最小公倍数的倍数组成的等差数列的和)。
解:
思路2程序如下:
#include <stdio.h>
typedef int INT;
typedef char CHAR;
/*****************************************************************************
* 函数:gcd *
* 参数:a:数字1. *
* b:数字2. *
* 返回值:返回a和b的最大公约数. *
* 功能:计算并返回a和b的最大公约数(递归版本). *
*****************************************************************************/
/*
INT gcd(INT a, INT b)
{
if (0 == b)
return a;
return gcd(b, a % b);
}
*/
/*****************************************************************************
* 函数:gcd *
* 参数:a:数字1. *
* b:数字2. *
* 返回值:返回a和b的最大公约数. *
* 功能:计算并返回a和b的最大公约数(循环版本). *
*****************************************************************************/
INT gcd(INT a, INT b)
{
INT nTem;
while (0 != b)
{
nTem = b;
b = a % b;
a = nTem;
}
return a;
}
/*****************************************************************************
* 函数:lcm *
* 参数:a:数字1. *
* b:数字2. *
* 返回值:返回a和b的最小公倍数. *
* 功能:计算并返回a和b的最小公倍数. *
* 说明:调用函数:INT gcd(INT a, INT b); *
*****************************************************************************/
INT lcm(INT a, INT b)
{
return a / gcd(a, b) * b;
}
/*****************************************************************************
* 函数:CalSum *
* 参数:a:数字1. *
* b:数字2. *
* nMax:计算上限. *
* 返回值:返回计算结果. *
* 功能:计算并返回小于nMax的a,b的所有倍数和. *
* 说明:调用函数:INT lcm(INT a, INT b); *
*****************************************************************************/
INT CalSum(INT a, INT b, INT nMax)
{
INT nLcm;
INT nSum;
INT nSub;
nMax--;
//计算a,b所有倍数的和
nSum = 0;
nSum += (a + nMax / a * a) * (nMax / a) / 2;
nSum += (b + nMax / b * b) * (nMax / b) / 2;
//计算a,b最小公倍数的所有倍数和
nLcm = lcm(a, b);
nSub = (nLcm + nMax / nLcm * nLcm) * (nMax / nLcm) / 2;
return nSum - nSub;
}
INT main(INT argc, CHAR *argv[])
{
INT a, b;
INT nMax;
INT nRes;
printf("请输入计算倍数和的两个数字(数字范围%d~%d):\n", (INT)0, ~(1<<(sizeof(INT)*8-1)));
scanf("%d %d", &a, &b);
printf("请输入计算上限(数字范围%d~%d):\n", (INT)0, ~(1<<(sizeof(INT)*8-1)));
scanf("%d", &nMax);
nRes = CalSum(a, b, nMax);
printf("结果:\n%d\n", nRes);
printf("按回车键退出...");
fflush(stdin);
getchar();
return 0;
}