二维数组的前缀和(为了计算子矩阵和)

Posted on 2022-11-07 11:06  金色的省略号  阅读(214)  评论(0编辑  收藏  举报

  1、二维数组的前缀和  

  

  设二维数组,int arr[5][7];,以 arr[1][1] 作为矩形的左上角坐标,以此开始存储数据,数组最左边,最上边不存储数据,为空

  设二维数组,int sum[5][7];,用以保存 arr 数组的前缀和,计算公式:sum[i][j] = arr[i][j] + sum[i-1][j] + sum[i][j-1] - sum[i-1][j-1];,即  (i,j) 坐标的元素 + (i-1,j)为矩形右下角的坐标的 蓝色矩形框  内的元素 + (i,j-1)为矩形右下角的坐标的 黄色矩形框 内的元素 - 多加的(i-1,j-1)为矩形右下角的坐标的矩形的元素

  2、子矩阵的和

  

  计算以(x1,y1)为左上角坐标,以(x2,y2)为右下角坐标的矩形内的元素的和(子矩阵),计算公式:sum[x2][y2]-sum[x1-1][y2]-sum[x2][y1-1]+sum[x1-1][y1-1];,即以(x2,y2)为右下角坐标的矩形内的元素 - 以(x1-1,y2)为右下角坐标的  绿色矩形 内的元素 - 以(x2,y1-1)为右下角坐标的 红色矩形 内的元素 + 多减去的以(x1-1,y1-1)为右下角坐标的矩形内的元素

#include <stdio.h>

int arr[101][101];
int sum[101][101];

int main()
{        
    int i,j;
    
    //填写数据    
    arr[1][1]=1;
    for(i=1,j=2; j<=100; ++j)  //第一行  比左边大2
        arr[i][j] = arr[i][j-1] + 2;
    for(i=2;i<=100;i++)        //第二行开始 比上面大1
    {
        for(j=1;j<=100;j++)
        {
            arr[i][j] = arr[i-1][j] + 1;          
        }
    }
    //计算sum数组 ,二维数组的前缀
    for( i=1; i<=100; ++i){ //
        for( j=1; j<=100; ++j){//
            sum[i][j] = arr[i][j] + sum[i-1][j] + sum[i][j-1] - sum[i-1][j-1];
        }    
    }
    
    int x1,y1,x2,y2;  //左上坐标,右下坐标,构成的子矩阵
    
    for(x1=1; x1<=100; ++x1)
    {
        for( y1=1; y1<=100; ++y1)
        {                
            for(x2=x1+1; x2<=100; ++x2){
                for(y2 = y1+1; y2<=100; ++y2){
                    int ret = sum[x2][y2]-sum[x1-1][y2]-sum[x2][y1-1]+sum[x1-1][y1-1];
                    if(ret>2022)
                        break;                    
                    if(ret==2022){
                        printf("%d,%d,%d,%d\n",x1,y1,x2,y2);
                        goto end;
                    }                
                }
            }
        }
    }
    
    end:
    
    for(i=x1; i<=x2; ++i){
        for(j=y1; j<=y2;++j){
            printf("%d,",arr[i][j]);
        }
        printf("\n");
    }
    
    printf( "%d\n", (x2-x1+1 ) * (y2-y1+1 )  );

    return 0;
}