PTA sdut-C语言实验-区间之和

给定一个由 n 个整数组成的序列A1,A2,……, An 和两个整数L,R,你的任务是写一个程序来计算序列号在L,R 这段位置区间内所有数的总和。

输入格式:
输入只有一组测试数据:
测试数据的第一行为一个整数 n (1< n < 10000);
第二行为 n 个 int 类型的整数;
第三行为两个整数 L,R(0 < L < R <= n)。
输出格式:
输出序列号在区间[L,R]内所有数的和,数据保证和在 int 类型范围内。

输入样例:

5
3 5 6 2 9
2 4

输出样例:

13

1.常规做法

根据题目要求遍历数组指定区间即可(注意数据第一个位置是1,要从1开始读入数组)

#include<stdio.h>
int main()
{
    int n, l, r, a[10010];
    scanf("%d", &n);
    for (int i = 1; i <= n; i ++)
        scanf("%d", &a[i]);
    int sum = 0;
    scanf("%d %d", &l, &r);
    for (int i = l; i <= r; i ++)
        sum += a[i];
    printf("%d", sum);
    return 0;
}

2.前缀和做法

1.前缀和介绍

前缀和的基本思想是通过预先计算数组中每个位置的前缀和,然后利用这些前缀和快速计算任意区间的和,而不必每次都重新遍历整个区间。
可以将前缀和类比于数学中的数列和
在数列中,已知前n项数列之和,若是求数量第n个数的值可通过以下公式计算:

a n = S n − S n − 1 ​ a_n=S_n-S_{n -1} ​ an=SnSn1

通过前缀和求某个区间值的思路也是如此,先将前1项,前2项,前3项…前n项的和分别求出,若是想求某个区间的和便可通过大区间减小区间求出。

2.前缀和的优势

仅是求一组数据的区间和,前缀和并没有明显优势,如果数据为多组,可以通过前缀和预先算出每个区间的和,对于每组数据只需做减法运算即可,无需再次遍历。这样做可以用空间换时间,大大减少了程序运行时间。

3.前缀和在本题中的应用

了解了前缀和后,读者需要思考该如何求出一个数组的前缀和。
首先,开辟一个数组来储存数据,既然是要求和,就需要再开辟一个数组来存储数据之和。
以下是前缀和的通用写法:

for (int i = 0; i < n; i ++)
	s[i] = s[i - 1] + a[i];

其中s[i]用来储存前 i 的数的总和
本题第一个数的下标为1,所以前缀和应用到本题中可以改写为:

for (int i = 1; i <= n; i ++)
	s[i] = s[i - 1] + a[i];

对于样例,想要求2到4区间的和,就需要用s[4] - s[1],通过观察我们不难发现s[4] - s[1]其实就是

s[r] - s[l - 1]

这是前缀和的关键以及易错点,减号右侧数组的下标需要基于题目给的数据减去一,以保证覆盖区间内的每个数。
以下是完整代码:

#include<stdio.h>
int main()
{
    int n, a[10010], l, r, s[10010];
    scanf("%d", &n);
    
    for (int i = 1; i <= n; i ++)
        scanf("%d", &a[i]);
    
    scanf("%d %d", &l, &r);
    
    for (int i = 1; i <= n; i ++)
        s[i] = s[i - 1] + a[i];
    
    printf("%d", s[r] - s[l - 1]);
    return 0;
}

本题使用的前缀和仅是一维前缀和,想要深入了解二维前缀和以及差分可以阅读以下文章。

【学习总结】一、二维前缀和 && 一、二维差分

前缀和与差分 图文并茂 超详细整理(全网最通俗易懂)

  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

比奇堡碌碌无为比目鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值