算法笔记.差分.差分矩阵

题目:

输入一个 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
1≤x1≤x2≤n
1≤y1≤y2≤m
−1000≤c≤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

我的代码: 

#include 
#include 
using namespace std;
const int N = 1010;
int board[N][N];
int changesum[N][N];
int n,m,q;

void insert(int x1,int y1,int x2,int y2,int elem)
{
    changesum[x1][y1] += elem;
    changesum[x1][y2+1] -= elem;
    changesum[x2+1][y1]-=elem;
    changesum[x2+1][y2+1]+=elem;
}


int main()
{
    cin>>n>>m>>q;
    for(int i =1;i<=n;i++)
    {
        for(int j = 1;j<=m;j++)
        {
            cin>>board[i][j];
        }
    }
    
    
    while(q--)
    {
        int x1,y1,x2,y2,c;
        cin>>x1>>y1>>x2>>y2>>c;
        insert(x1,y1,x2,y2,c);
    }
    
    for(int i =1;i<=n;i++)
    {
        for(int j = 1;j<=m;j++)
        {
            changesum[i][j]=changesum[i][j]+changesum[i][j-1]+changesum[i-1][j]-changesum[i-1][j-1];
        }
    }
    
    for(int i =1;i<=n;i++)
    {
        for(int j = 1;j<=m;j++)
        {
            cout <

思路: 

  1. 和数值类似,都是效果累积和消除恢复。
  2. 先来回顾一下:
    矩阵的前缀和:
        s[i][j]=a[i][j] + s[i-1][j] + s[i][j-1] - s[i-1][j-1]
    (x1,y1)到(x2,y2)矩阵的和:
       
    s = s[x2][y2] - s[x1-1][y2] - s[x2][y1-1] + s[x1-1][x2-1]

    (X1-1,y1-1)

    (x1-1,y2)

    (x1,y1)

    (x2,y1-1)

    (x2,y2)


    可见:关键坐标:
      (x2,y2)、(x1-1,y2)、(x2,y1-1)  、(x1-1,x2-1)
  3. 那么对于变化效果的累加,我们可以参考(x1,y1)到(x2,y2)矩阵的和的求法:
    重点关注(x2,y2)、(x1-1,y2)、(x2,y1-1)  、(x1-1,x2-1),根据之前一维差分的经验,还需要考虑(x1+1,y2)、(x2,y1+1)、(x2+1,y2+1)这些坐标来消除效果。
    我们以1 1 2 2 1为例。
    3.1.(x2,y2)+ 操作数(1)   
    3.2.(x1+1,y2)、(x2,y1+1)- 操作数(1)     消除累积效果
    3.3.由(x2+1,y2+1)被(x1+1,y2)、(x2,y1+1)- 操作数(1),影响了2次,所以重新补上操作数(1)

    (x1,y1)

    +1

    (x1,y2+1)

    -1

    (x2,y2)

    (x2+1,y2)

    -1

    (x2,y2)

    +1

  4. 求效果矩阵:

0

0

0

0

0

0

+1

+1

+1

0

1+0-0+(-1)

0

+1

+1

+1

0

1+0-1+0

0

+1

+1

+1

0

1+0-1+0

0

0

0+1-0+(-1)

0

0+1-1+0

0

0+1-1+0

0

0+0-1+1

     5. 所以:核心就是一下代码对操作效果的处理

void insert(int x1,int y1,int x2,int y2,int elem)
{
    changesum[x1][y1] += elem;
    changesum[x1][y2+1] -= elem;
    changesum[x2+1][y1]-=elem;
    changesum[x2+1][y2+1]+=elem;
}

 

你可能感兴趣的:(算法,笔记,矩阵)