求一千以内3或者5的倍数的和【三种解法:从小白到进阶!】

😊😊 😊😊
不求点赞,只求耐心看完,指出您的疑惑和写的不好的地方,谢谢您。本人会及时更正感谢。希望看完后能帮助您理解算法的本质
😊😊 😊😊

一、题目:

=
在这里插入图片描述

二、暴力做法:

1、暴力做法!直接一个一个枚举判断!

#include<stdio.h>

int sum; // 求和! 

int main ()
{
	int i, j;
	
	for (i=3; i < 1000; i ++)
	{
		if (i % 3 == 0 || i % 5 == 0)
		{
			sum += i;
		}
	}
	
	printf ("%d", sum);
	
	return 0;
}

三、递归:

递归求解的思路可以考虑将问题拆分为两个子问题:

求小于n的自然数中所有3的倍数之和。
求小于n的自然数中所有5的倍数之和。
最终结果为这两个子问题的和。

为了避免重复计算(15,45....会重复累计!!),可以使用递归函数来处理这两个子问题。

#include <iostream>
using namespace std;

int sum(int n) {
    if (n <= 0) {
        return 0;
    }
    int cur = n - 1;
    if (cur % 3 == 0 || cur % 5 == 0) {
        return cur + sum(cur);
    } else {
        return sum(cur);
    }
}

int main() {
    cout << sum(1000) << endl;  // 输出233168
    return 0;
}

四、求和公式:等差数列

首先,我们可以得到所有小于 n n n 3 3 3 的倍数的和为 3 + 6 + 9 + . . . + 3 × ⌊ n − 1 3 ⌋ 3+6+9+...+3\times \lfloor\frac{n-1}{3}\rfloor 3+6+9+...+3×3n1,这个和可以用等差数列求和公式求出: ( 3 + ⌊ n − 1 3 ⌋ × 3 ) × ⌊ n − 1 3 ⌋ 2 \frac{(3+\lfloor\frac{n-1}{3}\rfloor \times 3) \times \lfloor\frac{n-1}{3}\rfloor}{2} 2(3+3n1×3)×3n1

同样地,我们可以得到所有小于 n n n 5 5 5 的倍数的和为 5 + 10 + 15 + . . . + 5 × ⌊ n − 1 5 ⌋ 5+10+15+...+5\times \lfloor\frac{n-1}{5}\rfloor 5+10+15+...+5×5n1,这个和可以用等差数列求和公式求出: ( 5 + ⌊ n − 1 5 ⌋ × 5 ) × ⌊ n − 1 5 ⌋ 2 \frac{(5+\lfloor\frac{n-1}{5}\rfloor \times 5) \times \lfloor\frac{n-1}{5}\rfloor}{2} 2(5+5n1×5)×5n1

但是,由于上述两个求和公式中都有一个 ⌊ n − 1 x ⌋ \lfloor\frac{n-1}{x}\rfloor xn1,其中 x x x 可能是 3 3 3 5 5 5,我们需要避免重复计算。因此,我们可以再加上所有小于 n n n 15 15 15 的倍数的和,即 15 + 30 + 45 + . . . + 15 × ⌊ n − 1 15 ⌋ 15+30+45+...+15\times \lfloor\frac{n-1}{15}\rfloor 15+30+45+...+15×15n1。但是注意到 15 15 15 的倍数在计算 3 3 3 的倍数和 5 5 5 的倍数时已经被算过了,所以需要将这部分和减去。

综上,小于 n n n 的所有 3 3 3 5 5 5 的倍数之和为: ( 3 + ⌊ n − 1 3 ⌋ × 3 ) × ⌊ n − 1 3 ⌋ 2 + ( 5 + ⌊ n − 1 5 ⌋ × 5 ) × ⌊ n − 1 5 ⌋ 2 − ( 15 + ⌊ n − 1 15 ⌋ × 15 ) × ⌊ n − 1 15 ⌋ 2 \frac{(3+\lfloor\frac{n-1}{3}\rfloor \times 3) \times \lfloor\frac{n-1}{3}\rfloor}{2}+\frac{(5+\lfloor\frac{n-1}{5}\rfloor \times 5) \times \lfloor\frac{n-1}{5}\rfloor}{2}-\frac{(15+\lfloor\frac{n-1}{15}\rfloor \times 15) \times \lfloor\frac{n-1}{15}\rfloor}{2} 2(3+3n1×3)×3n1+2(5+5n1×5)×5n12(15+15n1×15)×15n1

代码如下:

#include <iostream>

using namespace std;

int main() {
    int n = 1000;
    int sum = 0;

    // 计算3的倍数之和
    int m3 = (n - 1) / 3;
    sum += 3 * m3 * (m3 + 1) / 2;

    // 计算5的倍数之和
    int m5 = (n - 1) / 5;
    sum += 5 * m5 * (m5 + 1) / 2;

    // 排除重复计算的15的倍数之和
    int m15 = (n - 1) / 15;
    sum -= 15 * m15 * (m15 + 1) / 2;

    cout << sum << endl;

    return 0;
}

在这里插入图片描述

草稿:

//233168;
//266333:表明有存在重复的计算:如:15, 45, 75...都是3和5的倍数,由于3和5的倍数是分开计算的,
//所以说最后造成了累加两次! 

//没有考虑重复累加计算的递归代码: 
#include<iostream>

using namespace std;

int sum;

void dfs(int m3, int m5)	//两个参数分别依次表示3的倍数,5的倍数! 
{
	if (m3 >= 10 && m5 >= 10) 	//递归的出口!
		return ;	//搜索结束! 

	if (m3 < 10) sum += m3;
	if (m5 < 10) sum += m5;
	dfs (m3 + 3, m5 + 5);	//逐步累加! 
}

int main()
{
	dfs(3, 5);	//递归从3和5的一倍开始!
	cout << sum << endl; 
	return 0;
} 
#include<stdio.h>

int sum; // 求和! 

int main ()
{
	int i, j;
	
	for (i=3; i < 10; i ++)
	{
		if (i % 3 == 0 || i % 5 == 0)
		{
			sum += i;
		}
	}
	
	printf ("%d", sum);
	
	return 0;
}

//数学公式: 
#include<iostream>

using namespace std;

int main()
{
	cout << 333*(3+999)/2 + 199*(1000)/2 << endl;
	return 0; 
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值