FZU 2080 最大差值 二维单调队列(甚是巧妙……)

 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 }

 

 

posted @ 2013-11-24 18:35  YaLing  阅读(418)  评论(0编辑  收藏  举报