zoukankan      html  css  js  c++  java
  • 理想的正方形(单调队列在二维的应用)

    理想的正方形

     

    题解:

    用单调队列分别维护行与列。

    这里只讲求 n*n 区间内的最大值的维护方法,最小值同样的方法维护即可。

    具体实现方法:

    • 遍历每一行,从上到下维护每一列的每一段n长度内的最大值,得到y_max数组;
    • 之后遍历y_max数组,也是遍历每一行,不过这时候要从左到右维护了,也就是行内维护,维护每一行内长度为n的区间内的最大值,得到x_max数组;
    • x_max数组就是原数组从左到右,从上到下每一个n*n区间内的最大值了。

     

    代码说明:

    原数组:mat,列数组:Q;

    遍历每一行,当行达到了n,就说明列向已经满足了n,这个时候就开始在行内维护n长度的最大值了(也就是说我的代码并没有完全等到y_max构造完就开始构造x_max了)

    AC_Code:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int maxn=1e3+10;
     4 const int inf = 0x3f3f3f3f;
     5 
     6 struct Container{
     7     deque<int> qmin;
     8     deque<int> qmax;
     9     Container():qmin(), qmax() {}
    10     void push(int n){
    11         while( !qmin.empty() && qmin.back()>n ) qmin.pop_back();
    12         qmin.push_back(n);
    13         while( !qmax.empty() && qmax.back()<n ) qmax.pop_back();
    14         qmax.push_back(n);
    15     }
    16     void pop(int n){
    17         if( qmin.size() && qmin.front()==n ) qmin.pop_front();
    18         if( qmax.size() && qmax.front()==n ) qmax.pop_front();
    19     }
    20     int _max(){
    21         return qmax.front();
    22     }
    23     int _min(){
    24         return qmin.front();
    25     }
    26 };
    27 
    28 int main()
    29 {
    30     int a,b,n;
    31     scanf("%d%d%d",&a,&b,&n);
    32     vector<vector<int> > mat(a,vector<int>(b));
    33     for(auto &v: mat){
    34         for(auto &i: v){
    35             scanf("%d",&i);
    36         }
    37     }
    38     vector<Container>Q(b);//
    39     int ans = inf;
    40     for(int i=0; i<a; i++){
    41         if( i>=n ){                    //纵向维护
    42             for(int j=0;j<b;j++){
    43                 Q[j].pop(mat[i-n][j]);//因为是单调维护,所以把mat[i-n][j]相同的值删掉就相当于把他及之前的数都给删掉了
    44             }
    45         }
    46         for(int j=0;j<b;j++){       //纵向维护
    47             Q[j].push(mat[i][j]);
    48         }
    49         if( i<n-1 ) continue;       //因为要是n*n的,所以首先要满足纵向长度达到了n
    50         Container C;
    51         for(int j=0;j<b;j++){       //横向维护
    52             if( j-n>=0 ){
    53                 C.pop(Q[j-n]._max());
    54                 C.pop(Q[j-n]._min());
    55             }
    56             C.push(Q[j]._max());
    57             C.push(Q[j]._min());
    58             if( j>=n-1 ) ans = min(ans,C._max()-C._min());
    59         }
    60     }
    61     printf("%d
    ",ans);
    62     return 0;
    63 }
     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int maxn=1e3+10;
     4 const int inf = 0x3f3f3f3f;
     5 
     6 struct node{
     7     int val;
     8     int idx;
     9 };
    10 deque<node>col_qmin[maxn], col_qmax[maxn], row_qmin, row_qmax;
    11 int mat[maxn][maxn];
    12 
    13 int main()
    14 {
    15     int a,b,n;
    16     scanf("%d%d%d",&a,&b,&n);
    17     for(int i=0;i<a;i++) for(int j=0;j<b;j++) scanf("%d",&mat[i][j]);
    18     int ans = inf;
    19     for(int i=0; i<a; i++){
    20         if( i>=n ){
    21             for(int j=0;j<b;j++){
    22                 while( col_qmin[j].size() && col_qmin[j].front().idx<=i-n ) col_qmin[j].pop_front();
    23                 while( col_qmax[j].size() && col_qmax[j].front().idx<=i-n ) col_qmax[j].pop_front();
    24             }
    25         }
    26         for(int j=0;j<b;j++){
    27             while( col_qmin[j].size() && col_qmin[j].back().val>mat[i][j] ) col_qmin[j].pop_back();
    28             col_qmin[j].push_back(node{mat[i][j],i});
    29             while( col_qmax[j].size() && col_qmax[j].back().val<mat[i][j] ) col_qmax[j].pop_back();
    30             col_qmax[j].push_back(node{mat[i][j],i});
    31         }
    32 
    33         if( i<n-1 ) continue;
    34         row_qmin.clear(); row_qmax.clear();
    35 
    36         for(int j=0;j<b;j++){
    37             if( j>=n ){
    38                 while( row_qmin.size() && row_qmin.front().idx<=j-n ) row_qmin.pop_front();
    39                 while( row_qmax.size() && row_qmax.front().idx<=j-n ) row_qmax.pop_front();
    40             }
    41             while( row_qmin.size() && row_qmin.back().val>col_qmin[j].front().val ) row_qmin.pop_back();
    42             row_qmin.push_back(node{col_qmin[j].front().val,j});
    43             while( row_qmax.size() && row_qmax.back().val<col_qmax[j].front().val ) row_qmax.pop_back();
    44             row_qmax.push_back(node{col_qmax[j].front().val,j});
    45 
    46             if( j>=n-1 ){
    47                 ans = min(ans,row_qmax.front().val-row_qmin.front().val);
    48             }
    49         }
    50     }
    51     printf("%d
    ",ans);
    52     return 0;
    53 }
  • 相关阅读:
    《国富论》
    DataGridView
    《ASP.NET Core 3框架揭秘》
    看见
    英语常用词汇
    《未选择的路》
    Redis实战(20)Redis 如何从海量数据中查询出某一个 Key?
    .NET 程序集Assembly使用
    ExtJs基础知识总结:自定义弹窗和ComboBox自动联想加载(四)
    ExtJs基础知识总结:Dom、IFrame和TreePanel、TabPanel(三)
  • 原文地址:https://www.cnblogs.com/wsy107316/p/14120664.html
Copyright © 2011-2022 走看看