Thinking: each row and column in a monotonous maintenance queue.
Specific method: a first value for each row of a maintenance queue monotonous, and A [] [] maximum value for each interval, respectively the minimum presence of X-[] [] and X [] [] in.
Then the X-[] [] and X [] [] are stored respectively maximum and minimum values within the rectangle of 1 × n. X-[i] [J ] of the memory i of row j ~ j + n-1 rectangular column the maximum value. Similarly, X [i] [J] storage of the i first row j ~ j + n-1 rectangular column minimum.
Then again these values on each column to maintain two arrays, the X-[] [] is the maximum value in each interval with the Y [] [] maintenance, the X [] [] in each section the minimum value Y [] [] maintenance. Then Y [i] [j] stored X-[] [] the first i ~ i + n-1 oblong maximum row j-th column. Similarly y [i] [j] stored X [] [] the first i ~ i + n-1 rectangular row j-th column of the minimum value.
Therefore, Y [i] [j] real storage as in a [i ~ i + n- 1] [j ~ j + n-1] is the largest, that is i, j is the upper left corner, the side length n the maximum value of the square. Similarly, Y [I] [J] stored i.e. i, j is the top left side length n minimum value of the square.
Simulation process shown below:
Code
#include <bits/stdc++.h> using namespace std; int n,m,k,front,FRONT,back,BACK,ans; int a[1001][1001],q[1001],Q[1001]; int x[1001][1001],X[1001][1001]; int y[1001][1001],Y[1001][1001]; int main() { scanf("%d%d%d",&n,&m,&k); for (int I=1;I<=n;I++) for (int i=1;i<=m;i++) scanf("%d",&a[I][i]); for (int I=1;I<=n;I++) { FRONT=BACK=front=back=Q[1]=q[1]=1; for (int i=2;i<=m;i++) { while (a[I][i]>=a[I][Q[BACK]]&&FRONT<=BACK) BACK--; while (a[I][i]<=a[I][q[back]]&&front<=back) back--; BACK++;back++;Q[BACK]=i;q[back]=i; while (i-Q[FRONT]>=k) FRONT++; while (i-q[front]>=k) front++; if (i>=k) X[I][i-k+1]=a[I][Q[FRONT]],x[I][i-k+1]=a[I][q[front]]; } } for (int I=1;I<=m-k+1;I++) { FRONT=BACK=front=back=Q[1]=q[1]=1; for (int i=2;i<=n;i++) { while (X[i][I]>=X[Q[BACK]][I]&&FRONT<=BACK) BACK--; while (x[i][I]<=x[q[back]][I]&&front<=back) back--; BACK++;back++;Q[BACK]=i;q[back]=i; while (i-Q[FRONT]>=k) FRONT++; while (i-q[front]>=k) front++; if (i>=k) Y[i-k+1][I]=X[Q[FRONT]][I],y[i-k+1][I]=x[q[front]][I]; } } ans=0x3f3f3f3f; for (int I=1;I<=n-k+1;I++) for (int i=1;i<=m-k+1;i++) ans=min(ans,Y[I][i]-y[I][i]); printf("%d\n",ans); return 0; }