理想的正方形(单调队列在二维的应用)

理想的正方形

 

 

题解:

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

这里只讲求 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\n",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\n",ans);
52     return 0;
53 }

 

posted @ 2020-12-11 15:36  swsyya  阅读(213)  评论(0编辑  收藏  举报

回到顶部