赞
踩
目录
对于一个给定的二维数组 arr,它的二维差分数组 d 中 d[i][j] 可以用如下公式计算:
①
②
③
④
实际上,上面的公式是通过二维数组 arr 是二维差分数组的前缀和这个条件推导出来的,因此,不像一维差分定义那样直观。
二维差分的主要用处:快速地将一个区块中的所有元素都加上一个值 v。
使用差分可以将在数组 arr 上的区块操作转化为在差分数组 d 上的单点操作。转换方式如下:
假设区块左上角坐标为 (x1, y1),右下角坐标为 (x2, y2),对该区块中的每个元素都加上 v 等价于下面四个操作:
1.
2.
3.
4.
因为差分数组的前缀和相当于原数组,所以对差分数组进行以上四个单点操作后,就相当于给数组 arr 的区块加上一个值 v。
通过定义计算二维差分比较复杂,可以使用一种更巧妙的方法:将二维差分中的每个元素一个一个地插进去。
首先假设原二维数组 arr 的元素全为 0,那么二维差分数组 d 的元素显然也全为 0,这样完全符合定义。
接下来将 arr 中的每个元素依次更新为实际值。例如 arr[2][3] 的实际值为 5,那么就相当于给以 (2, 3) 坐标为左上角,(2, 3) 坐标为右下角的区块中的所有元素加上 5。
① d[2][3] += 5
② d[3][3] -= 5
③ d[2][4] -= 5
④ d[3][4] += 5
这样便得到了整个差分数组。
题目描述:
输入一个 n 行 m 列的整数矩阵,再输入 q 个操作,每个操作包含五个整数 x1, y1, x2, y2, c,其中 (x1, y1) 和 (x2, y2) 表示一个子矩阵的左上角坐标和右下角坐标。
每个操作都要将选中的子矩阵中的每个元素的值加上 c。
请你将进行完所有操作后的矩阵输出。
输入格式:
第一行包含整数 n, m, q。
接下来 n 行,每行包含 m 个整数,表示整数矩阵。
接下来 q 行,每行包含 5 个整数 x1, y1, x2, y2, c,表示一个操作。
输出格式:
共 n 行,每行 m 个整数,表示所有操作进行完毕后的最终矩阵。
数据范围:
1 ≤ n, m ≤1000, 1 ≤ q ≤100000, 0 ≤ x1 ≤ x2 ≤ n - 1, 0 ≤ y1 ≤ y2 ≤ m - 1, −1000 ≤ c ≤ 1000, −1000 ≤ 矩阵内元素的值 ≤ 1000
输入样例:
- 3 4 3
- 1 2 2 1
- 3 2 2 1
- 1 1 1 1
- 0 0 1 1 1
- 0 2 1 2 2
- 2 0 2 3 1
输出样例:
- 2 3 4 1
- 4 3 4 1
- 2 2 2 2
代码实现:
- #include <stdio.h>
-
- int arr[1000][1000];
- int d[1001][1001];
-
- void insert(int x1, int y1, int x2, int y2, int c)
- {
- d[x1][y1] += c;
- d[x2 + 1][y1] -= c;
- d[x1][y2 + 1] -= c;
- d[x2 + 1][y2 + 1] += c;
- }
-
- int main()
- {
- int n = 0, m = 0, q = 0;
- scanf("%d %d %d", &n, &m, &q);
- int i = 0;
- int j = 0;
- // 输入整数矩阵,并计算二维差分
- for (i = 0; i < n; i++)
- {
- for (j = 0; j < m; j++)
- {
- scanf("%d", &arr[i][j]);
- insert(i, j, i, j, arr[i][j]);
- }
- }
- // 进行 q 次操作
- while (q--)
- {
- int x1 = 0, y1 = 0, x2 = 0, y2 = 0;
- int c = 0;
- scanf("%d %d %d %d %d", &x1, &y1, &x2, &y2, &c);
- insert(x1, y1, x2, y2, c);
- }
- // 计算二维差分的前缀和,即原二维数组 arr
- arr[0][0] = d[0][0];
- for (j = 1; j < m; j++)
- {
- arr[0][j] = arr[0][j - 1] + d[0][j];
- }
- for (i = 1; i < n; i++)
- {
- arr[i][0] = arr[i - 1][0] + d[i][0];
- }
- for (i = 1; i < n; i++)
- {
- for (j = 1; j < m; j++)
- {
- arr[i][j] = arr[i - 1][j] + arr[i][j - 1] - arr[i - 1][j - 1] + d[i][j];
- }
- }
- // 输出
- for (i = 0; i < n; i++)
- {
- for (j = 0; j < m; j++)
- {
- printf("%d ", arr[i][j]);
- }
- printf("\n");
- }
- return 0;
- }

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。