Description kaibad非常喜欢二维矩阵,他想要跟大家分享二维矩阵的魅力,希望大家和他一起解决这个问题。 有一个二维矩阵,矩阵的长宽分别用 n,m表示,每个位置都有一个值val (0 <= val <= 10)。 kaibad使用了一种魔法,每次会给出小矩阵的左上角和右下角的坐标,分别为x1,y1,x2,y2,魔法会使小矩阵的每个位置值增加 P (0 <=p <= 10)。但kaibad很花心,他对不同的小矩阵施加的魔法可能不同(P值可能不同),希望你能帮他找出使用所有魔法后的总和最大的小矩阵,并输出该小矩阵的总和。 Input 第一行包含两个整数 n 和 m
第二行输入 n 行 m 列的矩阵
第 n+2 行 输入 kaibad 喜欢的小矩阵的总数 num
接下来 num 行,每行包含五个整数 x1,y1,x2,y2,P
(1 <= n, m, num, x <= 1000)
Output 输出使用完所有魔法后的这些小矩阵的总和的最大值 Sample Input 3 4
1 2 3 4
4 3 2 1
1 2 3 4
2
2 2 3 3 1
1 1 3 4 2Sample Output 58 Hint 魔法的效果是可以累加的 Source 20221016
分析,套用公式,以后注意先仔细读题再写,误当成每次操作后立刻求小方块数和,其实是完成操作后 在求,导致一直优化算法浪费了很多时间,得不偿失
#include <iostream> using namespace std; const int M=1005+10; int s[M][M]; int a[M][M]; int h[M][M]; struct lins{ int a1,a2,a3,a4; }id[M]; int main() { int n=0,m=0,temp; int x1=0,y1=0,x2=0,y2=0,p=0; scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) { for (int j = 1; j <= m; j++) { scanf("%d",&s[i][j]); a[i][j] = s[i][j] - s[i - 1][j] - s[i][j - 1] + s[i - 1][j - 1]; } } int num; scanf("%d",&num); int q[num]; int temp1=num; int k=0; int k1=0; while(num--) { scanf("%d%d%d%d%d", &x1, &y1, &x2, &y2, &p); id[k1].a1=x1; id[k1].a2=y1; id[k1].a3=x2; id[k1].a4=y2; k1++; a[x1][y1] += p; a[x2 + 1][y2 + 1] += p; a[x2 + 1][y1] -= p; a[x1][y2 + 1] -= p; } for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { a[i][j]+=a[i - 1][j] +a[i][j - 1] - a[i - 1][j - 1]; h[i][j] = a[i][j] + h[i - 1][j] + h[i][j - 1] - h[i - 1][j - 1]; } } for(int i=0;i<temp1;i++){ q[i] = h[id[i].a3][id[i].a4]-h[id[i].a3][id[i].a2-1]-h[id[i].a1-1][id[i].a4]+h[id[i].a1-1][id[i].a2-1]; } temp=0; for(int i=0;i<temp1;i++){ if(q[i]>temp){ temp=q[i]; } } printf("%d\n",temp); return 0; }