「这是我参与11月更文挑战的第26天,活动详情查看:2021最后一次更文挑战」
什么是二维矩阵的差分
二维矩阵的差分是二维矩阵前缀和的逆运算,那什么是二维矩阵的前缀和呢,可以参考这篇文章算法笔记——前缀和 - 掘金 (juejin.cn)
二维矩阵差分的公式
知道定义后就不难推出其中蕴含哲理行的公式了:
给以(x1, y1)为左上角,(x2, y2)为右下角的子矩阵中的所有元素加上c: S[x1, y1] += c, S[x2 + 1, y1] -= c, S[x1, y2 + 1] -= c, S[x2 + 1, y2 + 1] += c
一般差分会搭配二维矩阵的前缀和公式来使用:
s[x1,y1]+=s[x1-1,y1]+s[x1,y1-1]-s[x1-1,y1-1]
有了二维矩阵的差分就不用多次循环去进行元素的叠加,直接利用差分的性质就可以很轻松的得出答案。
具体题目信息
题目描述
在 n×n 的格子上有 m个地毯。
给出这些地毯的信息,问每个点被多少个地毯覆盖。
输入格式
第一行,两个正整数 n,m。意义如题所述。
接下来 mm行,每行两个坐标 (x1,y1)(x1,y1) 和 (x2,y2)(x2,y2),代表一块地毯,左上角是 (x1,y1)(x1,y1),右下角是 (x2,y2)(x2,y2)。
输出格式
输出 n 行,每行 n个正整数。
第 i 行第 j列的正整数表示 (i,j) 这个格子被多少个地毯覆盖。
输入输出样例
输入 #1复制
5 3
2 2 3 3
3 3 5 5
1 2 1 4
输出 #1复制
0 1 1 1 0
0 1 1 0 0
0 1 2 1 1
0 0 1 1 1
0 0 1 1 1
代码:
#include<iostream>
#include<stdio.h>
using namespace std;
const int N=1010;
int b[N][N];
void insert(int x1,int y1,int x2,int y2,int c){
b[x1][y1]+=c;// 构造出差分矩阵
b[x2+1][y1]-=c;
b[x1][y2+1]-=c;
b[x2+1][y2+1]+=c;
}
int main(){
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
b[i][j]=0;
}
}
while(m--){
int x1,y1,x2,y2;
cin>>x1>>y1>>x2>>y2;
insert(x1,y1,x2,y2,1);
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
b[i][j]+=b[i-1][j]+b[i][j-1]-b[i-1][j-1];// 求差分矩阵的前缀和
cout<<b[i][j]<<" ";
}
cout<<endl;
}
return 0;
}
\