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; }