单调队列30pts求助~~
查看原帖
单调队列30pts求助~~
393674
jixiang楼主2021/11/11 20:35
#include<bits/stdc++.h>
using namespace std;
const int N= 1e3+9;

int q[N];
int hh,tt;
int mx[N][N];
int mxi[N][N],mxa[N][N];
int res,idx,cnt;
int mxxi[N][N];
int mxxa[N][N];


int a,b,n;

signed main()
{
    res= INT_MAX;
    scanf("%d%d%d",&a,&b,&n);
    for(int i=1;i<=a;i++)
    {
        for(int j= 1;j<=b;j++)
        {
            scanf("%d",&mx[i][j]);
        }
    }


    //单调队列求修正一次矩形最大值
    for(int i=1;i<=a;i++)
    {
        cnt=0;
        hh=0;
        tt=-1;
        for(int j=1 ;j<=b;j++)
        {
            if(q[hh]<j-n+1)hh++;

            if(hh<=tt&&mx[i][q[tt]]<mx[i][j])tt--;
            q[++tt]= j;
            if(j>=n)mxa[i][++cnt]=mx[i][q[hh]];
        }
    }

    //单调队列求修正一次矩形最小值
    for(int i=1;i<=a;i++)
    {
        cnt=0;
        hh=0;
        tt=-1;
        for(int j=1 ;j<=b;j++)
        {
            if(q[hh]<j-n+1)hh++;

            if(hh<=tt&&mx[i][q[tt]]>mx[i][j])tt--;
            q[++tt]= j;
            if(j>=n)mxi[i][++cnt]=mx[i][q[hh]];
        }
    }

    //二次修正矩形求最大值的最小值
    for(int j=1;j<=cnt;j++)
    {
        idx= 0;
        hh=0;
        tt=-1;
        for(int i=1;i<=a;i++)
        {
            if(q[hh]<i-n+1)hh++;

            if(hh<=tt&&mxi[q[tt]][j]>mxi[i][j])tt--;
            q[++tt]= i;
            if(i>=n)
            {
                mxxi[++idx][j]=mxi[q[hh]][j];
                //cout<<p[idx]<<endl;
                //cout<<p[idx]<<" ";
            }
        }
        //puts("");
    }

    //puts("");





    for(int j=1;j<=cnt;j++)
    {
        hh=0;
        tt=-1;
        idx=0;
        for(int i=1;i<=a;i++)
        {
            if(q[hh]<i-n+1)hh++;

            if(hh<=tt&&mxa[q[tt]][j]<mxa[i][j])tt--;
            q[++tt]= i;
            if(i>=n)
            {
                //cout<<mxa[q[hh]][j]<<" ";
                mxxa[++idx][j]= mxa[q[hh]][j];
                //res= min(res,mxa[q[hh]][j]-p[++idx]);
            }
        }
        //puts("");
    }



    for(int i=1;i<=idx;i++)
    {
        for(int j=1;j<=cnt;j++)
        {
            //cout<<mxxi[i][j]<<" ";
            res= min(res, mxxa[i][j]-mxxi[i][j]);
        }
        //puts("");
    }

    printf("%d",res) ;

}


2021/11/11 20:35
加载中...