给定N*N矩阵,求子矩形满足里面最大元素最小元素之差不超过M
单调队列
枚举上边界,下边界,及右边界,
用两个单调队列,一个维护最大值,一个维护最小
求左边界
#include<bits/stdc++.h> using namespace std; int A[505][505]; #define sc(x) scanf("%d",&x); int ma[505]; int mi[505]; int q1[505]; int q2[505]; int main() { int T,N,M; sc(T); while(T--){ sc(N);sc(M); for(int i=1;i<=N;i++){ for(int j=1;j<=N;j++){ sc(A[i][j]); } } int ans=1; for(int i=1;i<=N;i++){///上 for(int j=1;j<=N;j++)ma[j]=0,mi[j]=1e5+7; for(int j=i;j<=N;j++){///下 for(int k=1;k<=N;k++){///列 ma[k]=max(ma[k],A[j][k]); mi[k]=min(mi[k],A[j][k]); } int l1=0,l2=0,r1=0,r2=0; for(int k=1,p=0;k<=N;k++){ for(;l1<r1&&ma[q1[r1-1]]<ma[k];)r1--; for(;l2<r2&&mi[q2[r2-1]]>mi[k];)r2--; q1[r1++]=k,q2[r2++]=k; for(;l1<r1&&l2<r2&&ma[q1[l1]]-mi[q2[l2]]>M;){ if(q1[l1]<q2[l2])p=q1[l1++]; else p=q2[l2++]; }//p位置不取 ans=max(ans,(j-i+1)*(k-p)); } } } cout<<ans<<' '; } }