题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1047
就是先对行做一遍单调队列,再对那个结果按列做一遍单调队列即可。
代码如下:
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int const maxn=1005; int a,b,n,m[maxn][maxn],hmn[maxn][maxn],mn,hmx[maxn][maxn],mx; int w[maxn],qmn[maxn],qmx[maxn],headn,tailn,headx,tailx,ans; int main() { scanf("%d%d%d",&a,&b,&n); for(int i=1,x;i<=a;i++) { headn=1;tailn=0;headx=1;tailx=0;// for(int j=1;j<=b;j++) { scanf("%d",&w[j]);int x=w[j]; if(j-qmn[headn]>=n)headn++;//位置而非个数 if(j-qmx[headx]>=n)headx++; while(headn<=tailn&&x<=w[qmn[tailn]])tailn--; while(headx<=tailx&&x>=w[qmx[tailx]])tailx--; qmn[++tailn]=j;qmx[++tailx]=j;// hmn[i][j]=w[qmn[headn]];hmx[i][j]=w[qmx[headx]]; } } ans=1e9; for(int j=1;j<=b;j++) { headn=1;tailn=0;headx=1;tailx=0; for(int i=1;i<=a;i++) { int x=hmn[i][j],y=hmx[i][j]; if(i-qmn[headn]>=n)headn++;// if(i-qmx[headx]>=n)headx++; while(headn<=tailn&&x<=hmn[qmn[tailn]][j])tailn--; while(headx<=tailx&&y>=hmx[qmx[tailx]][j])tailx--; qmn[++tailn]=i;qmx[++tailx]=i; mn=hmn[qmn[headn]][j];mx=hmx[qmx[headx]][j]; if(i<n||j<n)continue;//|| ans=min(ans,mx-mn); } } printf("%d",ans); return 0; }