• 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
    ", res);
    77     }
    78     return 0;
    79 }
  • 相关阅读:
    net中System.Security.Cryptography 命名空间 下的加密算法
    关于如何生成代码的帮助文档的链接
    Application.EnableVisualStyles();
    VS2010里属性窗口中的生成操作
    把普通的git库变成bare库
    MultiTouch camera controls source code
    android onTouch()与onTouchEvent()的区别
    iOS开发中常见的语句@synthesize obj = _obj 的意义详解
    java nio 快速read大文件
    使用ndk standalone工具链来编译某个平台下的库
  • 原文地址:https://www.cnblogs.com/yaling/p/3440324.html
Copyright © 2020-2023  润新知