题目原文
题目描述
输入一个
n
n
n 行
m
m
m 列的整数矩阵,再输入
q
q
q 个操作,每个操作包含五个整数
x
1
,
y
1
,
x
2
,
y
2
,
c
,
x1,y1,x2,y2,c,
x1,y1,x2,y2,c,其中
(
x
1
,
y
1
)
(x1,y1)
(x1,y1) 和
(
x
2
,
y
2
)
(x2,y2)
(x2,y2) 表示一个子矩阵的左上角坐标和右下角坐标。
每个操作都要将选中的子矩阵中的每个元素的值加上 c c c。
请你将进行完所有操作后的矩阵输出。
输入格式
第一行包含整数
n
,
m
,
q
n,m,q
n,m,q。
接下来 n n n 行,每行包含 m m m 个整数,表示整数矩阵。
接下来 q q q 行,每行包含 5 个整数 x 1 , y 1 , x 2 , y 2 , c , x1,y1,x2,y2,c, x1,y1,x2,y2,c, 表示一个操作。
输出格式
共
n
n
n 行,每行
m
m
m 个整数,表示所有操作进行完毕后的最终矩阵。
数据范围
1
≤
n
,
m
≤
1000
,
1≤n,m≤1000,
1≤n,m≤1000,
1
≤
q
≤
100000
,
1≤q≤100000,
1≤q≤100000,
1
≤
x
1
≤
x
2
≤
n
,
1≤x1≤x2≤n,
1≤x1≤x2≤n,
1
≤
y
1
≤
y
2
≤
m
,
1≤y1≤y2≤m,
1≤y1≤y2≤m,
−
1000
≤
c
≤
1000
,
−1000≤c≤1000,
−1000≤c≤1000,
−
1000
≤
矩阵内元素的值
≤
1000
−1000≤矩阵内元素的值≤1000
−1000≤矩阵内元素的值≤1000
输入样例:
3 4 3
1 2 2 1
3 2 2 1
1 1 1 1
1 1 2 2 1
1 3 2 3 2
3 1 3 4 1
输出样例:
2 3 4 1
4 3 4 1
2 2 2 2
解题思路
思路类似于 ACWing 797. 差分,将其从一维扩展至二维。
对 a [ i ] a[i] a[i] 求差分可得 b [ i ] b[i] b[i] ,二者之间有关系:
b [ i ] [ j ] = a [ i ] [ j ] − a [ i − 1 ] [ j ] − a [ i ] [ j − 1 ] + a [ i − 1 ] [ j − 1 ] b[i][j] = a[i][j] - a[i - 1][j] - a[i][j - 1] + a[i - 1][j - 1] b[i][j]=a[i][j]−a[i−1][j]−a[i][j−1]+a[i−1][j−1]
将选中的子矩阵中的每个元素的值加上 c c c 后,原矩阵矩阵将变为:
… … … … … … a x 1 y 1 + c … a x 1 y 2 + c … … ⋮ ⋱ ⋮ … … a x 2 y 1 + c … a x 2 y 2 + c … … … … … … \begin{matrix} \dots &\dots &\dots &\dots&\dots\\ \dots &a_{x{1}y{1}} + c& \dots & a_{x{1}y{2}} + c&\dots\\ \dots &\vdots&\ddots & \vdots &\dots\\ \dots &a_{x{2}y{1}} + c& \dots& a_{x{2}y{2}} + c&\dots\\ \dots &\dots &\dots &\dots &\dots\\ \end{matrix} ………………ax1y1+c⋮ax2y1+c………⋱………ax1y2+c⋮ax2y2+c………………
则此时差分矩阵变为(矩阵中省略号部分元素均未改变):
… … … … … … b x 1 y 1 + c … a x 1 y 2 − c … … ⋮ ⋱ ⋮ … … b x 2 y 1 − c … a x 2 y 2 + c … … … … … … \begin{matrix} \dots &\dots &\dots &\dots&\dots\\ \dots &b_{x{1}y{1}} + c& \dots & a_{x{1}y{2}} - c&\dots\\ \dots &\vdots&\ddots & \vdots &\dots\\ \dots &b_{x{2}y{1}} - c& \dots& a_{x{2}y{2}} + c&\dots\\ \dots &\dots &\dots &\dots &\dots\\ \end{matrix} ………………bx1y1+c⋮bx2y1−c………⋱………ax1y2−c⋮ax2y2+c………………
故每次操作只需对数组 b [ i ] b[i] b[i] 作如下变换即可:
b [ x 1 ] [ y 1 ] + = c , b [ x 1 ] [ y 2 + 1 ] − = c , b [ x 2 + 1 ] [ y 1 ] − = c , b [ x 2 + 1 ] [ y 2 + 1 ] + = c b[x1][y1] += c\ ,\ b[x1][y2 + 1] -= c\ ,\ b[x2 + 1][y1] -= c\ ,\ b[x2 + 1][y2 + 1] += c b[x1][y1]+=c , b[x1][y2+1]−=c , b[x2+1][y1]−=c , b[x2+1][y2+1]+=c
最后再逆运算即可求出变换后的 a [ i ] a[i] a[i] ,输出结果即可。
代码
#include <iostream>
using namespace std;
const int N = 1010;
int a[N][N], b[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]);
b[i][j] = a[i][j] - a[i - 1][j] - a[i][j - 1] + a[i - 1][j - 1];
}
}
while (q -- )
{
int x1, y1, x2, y2, c;
scanf("%d%d%d%d%d", &x1, &y1, &x2, &y2, &c);
b[x1][y1] += c;
b[x1][y2 + 1] -= c;
b[x2 + 1][y1] -= c;
b[x2 + 1][y2 + 1] += c;
}
for (int i = 1; i <= n; i ++ )
{
for (int j = 1; j <= m; j ++ )
{
a[i][j] = a[i - 1][j] + a[i][j - 1] - a[i - 1][j - 1] + b[i][j];
printf("%d ", a[i][j]);
}
printf("\n");
}
return 0;
}