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