1 /** 这道题甚是巧妙啊,也是看了别人的代码才A的……,我相信如果你看了以后也会茅塞顿开的 */
2 #include <iostream>
3 #include <cstdio>
4 using namespace std;
5 #define N 1005
6
7 int head1, tail1, head2, tail2, qMax[N][N], qMin[N][N], matrix[N][N];
8
9 struct node{
10 int v, id;
11 }q1[N], q2[N];
12
13 void addMax( int v, int id ) { //维护队列最大值
14 while( head1 < tail1 && q1[tail1-1].v <= v ) tail1--;
15 q1[tail1].v = v; q1[tail1++].id = id;
16 }
17
18 int getMaxNum( int id ) {
19 while( head1 < tail1 && q1[head1].id < id ) head1++;
20 return q1[head1].v;
21 }
22
23 void addMin( int v, int id ) {
24 while( head2 < tail2 && q2[tail2-1].v >= v ) tail2--;
25 q2[tail2].v = v; q2[tail2++].id = id;
26 }
27
28 int getMinNum( int id ) {
29 while( head2 < tail2 && q2[head2].id < id ) head2++;
30 return q2[head2].v;
31 }
32
33 int main() {
34 int n, m, r, c, i, j;
35 while(scanf("%d%d%d%d", &n, &m, &r, &c) != EOF) {
36 for( i = 0; i < n; ++i )
37 for( j = 0; j < m; ++j ) scanf("%d", &matrix[i][j]);
38
39 for( j = 0; j < m; ++j ) {
40 head1 = tail1 = head2 = tail2 = 0;
41 for( i = 0; i < r - 1; ++i ) {
42 addMax( matrix[i][j], i );
43 addMin( matrix[i][j], i );
44 }
45 /** 这里qMax[i][j]表示第j列, max( matrix[ i->(i+r) ][j] )中的最大值
46 * qMin[i][j],同上。
47 */
48 for( i = r - 1; i < n; ++i ) {
49 addMax( matrix[i][j], i );
50 qMax[i-r+1][j] = getMaxNum( i-r+1 );
51 addMin( matrix[i][j], i );
52 qMin[i-r+1][j] = getMinNum( i-r+1 );
53 }
54 }
55 /** 这里qMax[i][j]表示第j列, max( qMax[i][ j->(j+c) ] )中的最大值
56 * 即qMax[i][j]表示以(i,j)为左上角的一个r*c子矩阵中的最大值
57 * qMin[i][j],同上。
58 */
59 for( i = 0; i < n - c + 1; ++i ) {
60 head1 = tail1 = head2 = tail2 = 0;
61 for( j = 0; j < c - 1; ++j ) {
62 addMax( qMax[i][j], j );
63 addMin( qMin[i][j], j );
64 }
65 for( j = c - 1; j < m; ++j ) {
66 addMax( qMax[i][j], j );
67 qMax[i][j-c+1] = getMaxNum(j-c+1);
68 addMin( qMin[i][j], j );
69 qMin[i][j-c+1] = getMinNum(j-c+1);
70 }
71 }
72 int res = qMax[0][0] - qMin[0][0];
73 for( i = 0; i < n - r + 1; ++i )
74 for( j = 0; j < m - c + 1; ++j )
75 res = res > qMax[i][j] - qMin[i][j] ? res : qMax[i][j] - qMin[i][j];
76 printf("%d\n", res);
77 }
78 return 0;
79 }