1604

在这里插入图片描述

rc的矩阵用单调队列横向缩为r(c-n+1)矩阵,然后纵向缩为(r-n+1)*(c-n+1)矩阵,矩阵每一个点都代表着一个正方形的最值。

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<ctime>
#include<cstdio>
using namespace std;
const int maxn=2e5+5;
struct node
{
    int x,y;
} idm[maxn],idn[maxn];
int vmax[maxn],vmin[maxn],lm=1,ln=1,rm=0,rn=0,mp[2001][2001],valm[2001][2001],valn[2001][2001];
#define base1(xs,j,k)  \
while(lm<=rm&&vmax[rm]<=xs)rm--; \
vmax[++rm]=xs;    \
idm[rm].y=k; \
idm[rm].x=j; \

#define base2(xs,j,k) \
while(ln<=rn&&vmin[rn]>=xs)rn--; \
vmin[++rn]=xs;  \
idn[rn].y=k;    \
idn[rn].x=j;   \


#define sq(x,y,z,a) for(int i=x;i<=y;i++)for(int j=z;j<=a;j++)

#define getans() minn=min(minn,vmax[lm]-vmin[ln]);//cout<<"vmax"<<vmax[lm]<<' '<<"vmin "<<vmin[ln]<<" lm "<<idm[lm].x<<' '<<idm[lm].y<<' '<<lm<<" ln "<<idn[ln].x<<' '<<idn[ln].y<<' '<<ln<<endl;
int r,c,n,minn=0x3f3f3f3f;

void init()
{
    scanf("%d%d%d",&r,&c,&n);
    sq(1,r,1,c) scanf("%d",&mp[i][j]);
}
int main()
{
 
    init();
    for(int i=1; i<=r; i++)
    {
        lm=1,ln=1,rm=0,rn=0;
        for(int j=1; j<=c; j++)
        {
            base1(mp[i][j],i,j);
            base2(mp[i][j],i,j);
            int ym=idm[lm].y;

            int yn=idn[ln].y;
     
            while(ym<=j-n) {
                lm++;
                ym=idm[lm].y;
            }
            while(yn<=j-n) {
                ln++;
               yn=idn[ln].y;
            }
  
            valm[i][j]=vmax[lm];
            valn[i][j]=vmin[ln];
        }
    }
 
    for(int i=n; i<=c; i++){
    lm=1,ln=1,rm=0,rn=0;
        for(int j=1; j<=r; j++)
        {
          //  cout<<valm[j][i]<<">>>>"<<endl;
            base1(valm[j][i],j,i);
            base2(valn[j][i],j,i);
           int xm=idm[lm].x;

            int xn=idn[ln].x;

            while(xm<=j-n) {
                lm++;
                xm=idm[lm].x;
            }
            while(xn<=j-n) {
                ln++;
                xn=idn[ln].x;
            }
            valm[j][i]=vmax[lm];
            valn[j][i]=vmin[ln];
        }
      }

    sq(n,r,n,c)minn=min(valm[i][j]-valn[i][j],minn);
    cout << minn << endl;
    return 0;

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值