• 牛客多校第三场F Planting Trees 单调栈


    Planting Trees

    题意

    给出一个矩阵,求最大矩阵面积满足该矩阵中任2元素的绝对值之差小于等于M T<1000) (n<500)但是题目明示单组(n*3)可过

    分析

    又是矩阵问题,单调栈的第n次出现?这一题和之前的题不同的是,边界界定没有以前那么直白,变成了绝对值的问题,绝对值问题可以转化成最大最小的问题,那么如何枚举矩阵呢?不同于之前的简单的连续性可以传递的矩阵问题,这一题要枚举矩阵的上下边界,那枚举了上下边界如果计算当前上下边界上的矩形的最大面积,那就要用到单调栈了,固定上边界维护每一列的最大值最小值,并以此值来维护单调队列,以一个类似双指针的形式即可求出最大值。

    #include<bits/stdc++.h>
    using namespace std;
    #define F first
    #define S second
    const int maxn=500+5;
    int q1[maxn],q2[maxn],a[maxn][maxn],rowmin[maxn],rowmax[maxn];
    int n,m,t;
    long long ans=0;
    int main(){
        scanf("%d",&t);
        while(t--){
            scanf("%d%d",&n,&m);
            ans=0;
            for(int i=1;i<=n;i++){
                for(int j=1;j<=n;j++){
                    scanf("%d",&a[i][j]);
                }
            }
            for(int i=1;i<=n;i++){
                for(int k=1;k<=n;k++)rowmin[k]=rowmax[k]=a[i][k];
                for(int j=i;j<=n;j++){
                int head1=1,tail1=0;
                int head2=1,tail2=0;
                    for(int k=1;k<=n;k++){
                        rowmin[k]=min(rowmin[k],a[j][k]);
                        rowmax[k]=max(rowmax[k],a[j][k]);
                    }
                    int l=1;
                    for(int k=1;k<=n;k++){
                        if(tail1<head1){
                            q1[++tail1]=k;
                        }
                        else {
                            while(tail1>=head1&&rowmin[k]<=rowmin[q1[tail1]])tail1--;
                            q1[++tail1]=k;
                        }
                        if(tail2<head2){
                            q2[++tail2]=k;
                        }
                        else {
                            while(tail2>=head2&&rowmax[k]>=rowmax[q2[tail2]])tail2--;
                            q2[++tail2]=k;
                    }
                        while(l<=k&&rowmax[q2[head2]]-rowmin[q1[head1]]>m){
                            l++;
                            if(q2[head2]<l)head2++;
                            if(q1[head1]<l)head1++;
                        }
                        ans=max(ans,1ll*(k-l+1)*(j-i+1));
                 
                }
            }
            }
                cout<<ans<<endl;
        }
     
         
        return 0;
    }
    
  • 相关阅读:
    android 中使用AsyncTask实现简单的异步编程
    android TextView 垂直自动滚动
    (转)c3p0配置大全
    Android中在底端显示选项卡
    android 中ImageView的scaletype属性
    android 权限大全
    Palm应用开发之六 常用命令及debug
    android spinner 实现Text 和 value
    [转载]【职场宝典】面试官如何看待学历?
    起跑
  • 原文地址:https://www.cnblogs.com/ttttttttrx/p/11396007.html
Copyright © 2020-2023  润新知