P2216 Ideal Square

Posted by MisterWebz on Sun, 13 Oct 2019 23:20:37 +0200

Title Description

There is a matrix composed of integers of (a*b) from which you can find a square area of (n*n\\\\\\\\\

Input and output format

Input format:

The first behavior(3) integers represent the values of(a,b,n)

From the second line to the (a+1) line, each action (b) is a non-negative integer representing the number at the corresponding position in the matrix. Each row is separated by a space between two adjacent numbers.

Output format:

Only one integer is the minimum of the difference between the largest integer and the smallest integer in all (n*n\) square areas of the \\\\\\\\

\(Solution\)

This question is not serious \\\\\\\\\\\\
As a result, I finally looked at the solution, (woc?) monotone queue, and found that it was actually very simple.
As long as monotonic queues are made in each row, a matrix is formed.
Then the final matrix can be formed by monotonic queues for each column, i n which only statistics(\Sigma_i^{n-k+1}Sigma_j^{m-k+1} Max (ans, Ymax [i] [j]-Ymin [i] [j]])are needed.
Imaginally, make a monotonic queue for each row, and let(xmax[i][j] denote the maximum value of(j~j+k-1) in line(i)
Then, by rotating the resulting matrix, the one-dimensional operation that has not yet been compressed will be operated as above.
The following is an illustration, turned from \(luogu\) problem solving, in which \[[[[]][[[]]] \[[[[[]][[[[[]]] \[[[[[]][[]]][[[[]]]\[[[[[[[[]]][[[[[[[[[]]]]]\\[[[[[[[[]][[[[]]\[[[[[]]]]\\\].

Note that monotonic queues are subscripts to stored weights, which are monotonic. This is the conventional monotone queue writing, of course, you can also open a structure storage weight + subscript.
Then you just need to start with (2) because there is no (k=1)

\(Code\)

#include<cstdio>
#include<iostream>
#define maxn 1010
#define re register

using namespace std;

int ans=0x7fffffff,front1,back1,front2,back2;
int a[maxn][maxn],q1[maxn],q2[maxn];
int xmax[maxn][maxn],xmin[maxn][maxn];
int ymax[maxn][maxn],ymin[maxn][maxn];
int n,m,k;
int main()
{
    scanf("%d%d%d",&n,&m,&k);
    for(re int i=1;i<=n;++i)
     for(re int j=1;j<=m;++j)
      scanf("%d",&a[i][j]);
    for(re int i=1;i<=n;++i)
    {
        front1=front2=back1=back2=q1[1]=q2[1]=1;
        for(re int j=2;j<=m;++j)
        {
            while(a[i][j]>=a[i][q1[back1]]&&front1<=back1) back1--;
            while(a[i][j]<=a[i][q2[back2]]&&front2<=back2) back2--;
            back1++,back2++;
            q1[back1]=j,q2[back2]=j;
            while(j-q1[front1]>=k) front1++;
            while(j-q2[front2]>=k) front2++;
            if(j>=k) xmax[i][j-k+1]=a[i][q1[front1]],xmin[i][j-k+1]=a[i][q2[front2]];
                               
        }
    }
    for(re int j=1;j<=m-k+1;++j)
    {
        front1=front2=back1=back2=q1[1]=q2[1]=1;
        for(re int i=2;i<=n;++i)
        {
            while(xmax[i][j]>=xmax[q1[back1]][j]&&front1<=back1) back1--;
            while(xmin[i][j]<=xmin[q2[back2]][j]&&front2<=back2) back2--;
            back1++,back2++;
            q1[back1]=i,q2[back2]=i;
            while(i-q1[front1]>=k) front1++;
            while(i-q2[front2]>=k) front2++;
            if(i>=k) ymax[i-k+1][j]=xmax[q1[front1]][j],ymin[i-k+1][j]=xmin[q2[front2]][j];
        }
    }
    
    for(re int i=1;i<=n-k+1;++i)
    {
        for(re int j=1;j<=m-k+1;++j)
        {
            ans=min(ans,ymax[i][j]-ymin[i][j]);
        }
    }
    printf("%d\n",ans);
    return 0;
}

Topics: PHP