http://ybt.ssoier.cn:8088/problem_show.php?pid=1282
方法一:暴力(40分)
1 #include<bits/stdc++.h> 2 using namespace std; 3 int n, a[105][105], ans=-(1<<30), sum=0; 4 int main() 5 { 6 scanf("%d", &n); 7 for(int i=1; i<=n; i++) 8 for(int j=1; j<=n; j++) 9 scanf("%d", &a[i][j]); 10 for(int x1=1; x1<=n; x1++)//左上角坐标 11 for(int y1=1; y1<=n; y1++) 12 for(int x2=x1; x2<=n; x2++)//右下角坐标 13 for(int y2=y1; y2<=n; y2++){ 14 sum=0; 15 for(int s=x1; s<=x2; s++)//枚举中间所有元素求和 16 for(int e=y1; e<=y2; e++) 17 sum+=a[s][e]; 18 ans=max(ans, sum); 19 } 20 printf("%d", ans); 21 return 0; 22 }
方法二:二维前缀和
1 #include<bits/stdc++.h> 2 using namespace std; 3 int n, a[105][105], pre_sum[105][105]; 4 int xy_sum;//子矩阵和 5 int ans=-(1<<30); 6 int main() 7 { 8 scanf("%d", &n); 9 for(int i=1; i<=n; i++) 10 for(int j=1; j<=n; j++) 11 scanf("%d", &a[i][j]); 12 13 //边界初始化 14 for(int i=1; i<=n; i++){ 15 pre_sum[1][i]=pre_sum[1][i-1]+a[1][i]; 16 pre_sum[i][1]=pre_sum[i-1][1]+a[i][1]; 17 } 18 19 //求前缀和 20 for(int i=1; i<=n; i++) 21 for(int j=1; j<=n; j++) 22 pre_sum[i][j]=pre_sum[i-1][j]+pre_sum[i][j-1]-pre_sum[i-1][j-1]+a[i][j]; 23 24 //测试前缀和 25 // printf(" "); 26 // for(int i=1; i<=n; i++){ 27 // for(int j=1; j<=n; j++) 28 // printf("%d ", pre_sum[i][j]); 29 // printf(" "); 30 // } 31 // printf(" "); 32 33 for(int x1=1; x1<=n; x1++)//左上角坐标 34 for(int y1=1; y1<=n; y1++) 35 for(int x2=x1; x2<=n; x2++)//右下角坐标 36 for(int y2=y1; y2<=n; y2++){ 37 38 xy_sum=pre_sum[x2][y2]-pre_sum[x2][y1-1]-pre_sum[x1-1][y2]+pre_sum[x1-1][y1-1];//注意细节,把当前行列不能减掉,所以要-1 此处容易出错 39 //printf("%d %d %d %d : %d ", x1, y1, x2, y2, xy_sum); 40 ans=max(ans, xy_sum); 41 } 42 printf("%d", ans); 43 return 0; 44 }