这几乎是二维前缀和的模板题。
众所周知,一维前缀和
s
u
m
i
sum_i
sumi的定义为:对有n个数的数列,
s
u
m
i
=
∑
k
=
1
i
a
i
sum_i=\sum \limits_{k=1}^{i}a_i
sumi=k=1∑iai
那么,二维前缀和
s
u
m
i
,
j
sum_{i,j}
sumi,j 自然就是对有n行m列的矩阵,
s
u
m
i
,
j
=
∑
i
=
1
n
∑
j
=
1
m
a
i
,
j
sum_{i,j}=\sum \limits_{i=1}^{n}\sum \limits_{j=1}^{m}a_{i,j}
sumi,j=i=1∑nj=1∑mai,j
这就是用了类比的思想。类似的思想有很多应用。比如在高数中,可以由定义在区间上的一元函数的许多定理、公式都可以扩展到定义在平面区域的二元函数。
而题目中是要求固定的CxC方阵,因此只要对二位前缀和做减法即可。注意重复减去的处理。
inline int calc(int i,int j,int c) {
int l=max(0,j-c),u=max(0,i-c); //最左边的列和最上边的行
return sum[i][j]-sum[u][j]-sum[i][l]+sum[u][l];
}
int main() {
//省略输入
for(int i=1; i<=n; i++) {
for(int j=1; j<=m; j++) {
scanf("%d",&a[i][j]);
sum[i][j]=sum[i][j-1]+a[i][j];
}
for(int j=1; j<=m; j++) sum[i][j]+=sum[i-1][j];
}
int maxi=0,maxj=0,maxn=-INF;
for(int i=c; i<=n; i++) {
for(int j=c; j<=m; j++) {
int now=calc(i,j,c);
if(now>maxn) {
maxn=now;
maxi=i;
maxj=j;
}
}
}
printf("%d %d",maxi-c+1,maxj-c+1);
return 0;
}