前言
✨本博客讲解 蓝桥杯C/C++ 备赛所涉及算法知识,此博客为第四讲:前缀和【习题】
前缀和【习题】详见博客:蓝桥杯第四讲–前缀和【习题】
前缀和算法模板详见博客:前缀和算法模板
本篇博客所包含习题有:
👊前缀和
👊子矩阵的和
博客内容以题代讲,通过讲解题目的做法来帮助读者快速理解算法内容,需要注意:学习算法不能光过脑,更要实践,请读者务必自己敲写一遍本博客相关代码!!!
前缀和
题目要求
题目描述:
输入一个长度为 n的整数序列。
接下来再输入 m 个询问,每个询问输入一对 l , r 。
对于每个询问,输出原序列中从第 l 个数到第 r 个数的和。
输入格式:
第一行包含两个整数 n 和 m 。
第二行包含 n 个整数,表示整数数列。
接下来 m 行,每行包含两个整数 l和 r ,表示一个询问的区间范围。
输出格式:
共 m 行,每行输出一个询问的结果。
数据范围:
1 ≤ l ≤ r ≤ n ,
1 ≤ n, m ≤ 100000,
−1000 ≤ 数列中元素的值 ≤ 1000
输入样例:
5 3
2 1 3 6 4
1 2
1 3
2 4
输出样例:
3
6
10
思路分析
一维前缀和板子题
代码
#include <cstdio> #include <algorithm> #include <cstring> using namespace std; const int N = 100010; int s[N]; int main() { int n, m; scanf("%d%d", &n, &m); for (int i = 1; i <= n; i ++ ) { int a; scanf("%d", &a); s[i] = s[i - 1] + a; } while (m -- ) { int l, r; scanf("%d%d", &l, &r); printf("%d\n", s[r] - s[l - 1]); } return 0; }
子矩阵的和
题目要求
题目描述:
输入一个 n 行 m 列的整数矩阵,再输入 q个询问,每个询问包含四个整数 x1, y1, x2, y2,表示一个子矩阵的左上角坐标和右下角坐标。
对于每个询问输出子矩阵中所有数的和。
输入格式:
第一行包含三个整数 n ,m ,q 。
接下来 n 行,每行包含 m 个整数,表示整数矩阵。
接下来 q 行,每行包含四个整数x1, y1, x2, y2,表示一组询问。
输出格式:
共 q 行,每行输出一个询问的结果。
数据范围:
1 ≤ n , m ≤ 1000,
1 ≤ q ≤ 200000,
1 ≤ x1 ≤ x2 ≤ n,
1 ≤y1 ≤y2 ≤ m,
−1000 ≤ 矩阵内元素的值 ≤ 1000
输入样例:
3 4 3
1 7 2 4
3 6 2 8
2 1 2 3
1 1 2 2
2 1 3 4
1 3 3 4
输出样例:
17
27
21
思路分析
二维前缀和板子题
代码
#include <cstdio> #include <algorithm> #include <cstring> using namespace std; const int N = 1010; int a[N][N], s[N][N]; int main() { int n, m, q; scanf("%d%d%d", &n, &m, &q); for (int i = 1; i <= n; i ++ ) for (int j = 1; j <= m; j ++ ) scanf("%d", &a[i][j]); for (int i = 1; i <= n; i ++ ) for (int j = 1; j <= m; j ++ ) s[i][j] = s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1] + a[i][j]; while (q -- ) { int x1, y1, x2, y2; scanf("%d%d%d%d", &x1, &y1, &x2, &y2); printf("%d\n", s[x2][y2] - s[x1 - 1][y2] - s[x2][y1 - 1] + s[x1 - 1][y1 - 1]); } return 0; }