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 ", res); 77 } 78 return 0; 79 }