【题意】c++
给定区域大小n*n的网格和m,要求输出最大的矩形知足任意两个位置的差值不超过m的面积。spa
【题解】code
思路:枚举上下边界和右边界,用两个单调队列维护最小左边界,更新最大面积。如何维护?以最大值为例,由于若是当前的最大最小值不知足<=m,那么咱们须要更小的最大值,因此须要的单调队列是递减的,所以在维护的时候咱们每次入队时弹出比当前最大值小的元素。队列
【代码】it
#include<bits/stdc++.h> using namespace std; const int inf=0x3f3f3f3f; int n,m,a[505][505],mx[505],mn[505],la[505],ra[505]; int q1[505],q2[505],l1,l2,r1,r2; int main() { int T; scanf("%d",&T); while(T--){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) scanf("%d",&a[i][j]); int ans=0; for(int l=1;l<=n;l++){ //初始化最大最小值 memset(mx,0,sizeof mx); memset(mn,inf,sizeof mn); for(int r=l;r<=n;r++){ l1=l2=r1=r2=0; for(int k=1,p=0;k<=n;k++){ //枚举右边界 //更新最大最小值 mx[k]=max(mx[k],a[r][k]); mn[k]=min(mn[k],a[r][k]); while(l1<r1&&mx[q1[r1-1]]<mx[k]) r1--; //弹出比MAX小的,保证单调队列递减 while(l2<r2&&mn[q2[r2-1]]>mn[k]) r2--; //弹出比MIN大的,保证单调队列递增 q1[r1++]=k,q2[r2++]=k; //进入单调队列 while(l1<r1&&l2<r2&&mx[q1[l1]]-mn[q2[l2]]>m){ //更新最小左边界 if(q1[l1]<q2[l2]) p=q1[l1++]; else p=q2[l2++]; } ans=max(ans,(r-l+1)*(k-p)); } } } printf("%d\n",ans); } return 0; }