首页 > 其他分享 >【题目-理想的正方形】 二维单调队列

【题目-理想的正方形】 二维单调队列

时间:2023-11-21 23:14:33浏览次数:39  
标签:int 队列 rmax ++ 正方形 二维 -- 单调

理想的正方形 (二维单调队列)

题目

题解

  • 题目很好做,主要学习一下二维单调队列的写法
  • 首先将每行各窗口内最值用单调队列维护出来,保存在rmax
  • 接着对rmax各列,将每列最值用单调队列维护出来,保存在cmax中,最后cmax中存的就是行和列窗口乘积范围的二维区间最值
  • 最小值同理

代码

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
#define x first
#define y second
typedef pair<int, int> PII;
const int N = 2e3 + 5;

int n, m, z;
int w[N][N];
int res = 0x3f3f3f3f;
int q[N], h, t;

int rmax[N][N], rmin[N][N];
int cmax[N][N], cmin[N][N];


void get_max(int i){
    h = 0, t = -1;
    for(int j = 1; j < z; ++ j) {
        while(h <= t && w[i][j] >= w[i][q[t]]) t--;
        q[++ t] = j;
    }
    for(int j = z; j <= m; ++ j) {
        while(h <= t && q[h] <= j - z) h ++;
        while(h <= t && w[i][j] >= w[i][q[t]]) t --;
        q[++ t] = j;
        rmax[i][j] = w[i][q[h]];
    }
}

void get_min(int i) {
    h = 0, t = -1;
    for(int j = 1; j < z; ++ j) {
        while(h <= t && w[i][j] <= w[i][q[t]]) t --;
        q[++ t] = j;
    }
    for(int j = z; j <= m; ++ j) {
        while(h <= t && q[h] <= j - z) h ++;
        while(h <= t && w[i][j] <= w[i][q[t]]) t --;
        q[++ t] = j;
        rmin[i][j] = w[i][q[h]];
    }
}

void get_max_c(int j) {
    h = 0, t = -1;
    for(int i = 1; i < z; ++ i) {
        while(h <= t && rmax[i][j] >= rmax[q[t]][j]) t --;
        q[++ t] = i;
    }
    for(int i = z; i <= n; ++ i) {
        while(h <= t && q[h] <= i - z) h ++;
        while(h <= t && rmax[i][j] >= rmax[q[t]][j]) t --;
        q[++ t] = i;
        cmax[i][j] = rmax[q[h]][j];
    }
}

void get_min_c(int j) {
    h = 0, t = -1;
    for(int i = 0; i < z; ++ i){
        while(h <= t && rmin[i][j] <= rmin[q[t]][j]) t --;
        q[++ t] = i;
    }
    for(int i = z; i <= n; ++ i) {
        while(h <= t && q[h] <= i - z) h ++;
        while(h <= t && rmin[i][j] <= rmin[q[t]][j]) t --;
        q[++ t] = i;
        cmin[i][j] = rmin[q[h]][j];
    }
}

int main() {
    scanf("%d%d%d",&n, &m, &z);
    for(int i = 1; i <= n; ++ i)
        for(int j = 1; j <= m; ++ j)
            scanf("%d",&w[i][j]);
    
    for(int i = 1; i <= n; ++ i) {
        get_max(i);
        get_min(i);
    }
    for(int j = z; j <= m; ++ j) {
        get_max_c(j);
        get_min_c(j);
    }
    int res = 0x3f3f3f3f;
    for(int i = z; i <= n; ++ i)
        for(int j = z; j <= m; ++ j)
            res = min(res, cmax[i][j] - cmin[i][j]);
    
    printf("%d\n",res);
    
    return 0;
}

标签:int,队列,rmax,++,正方形,二维,--,单调
From: https://www.cnblogs.com/A-sc/p/17847851.html

相关文章

  • 二维字符数组特殊提醒
    如果要对二维字符数组一个一个位置赋初值,一定要像下面这么做chars[5][5],s1[5][5];for(inti=0;i<5;i++)for(intj=0;j<4;j++)//一定要注意j最多只能到3,因为最后一个位置要用来放停止符{s[i][j]=j+(int)'0';s[i][4]='\0';//一定要手动给最后一个位置放停止符}for......
  • wxid批量转换微信号接口工具,自动转换二维码,开源API分享!
    这个是今天客户定制的,就是从微信群导出了很多WXID,然后实现通过WXID加好友,我就直接调用了微信的接口,说明一下这是微信公开的接口,不存在HOOK或者是逆向技术存在的,公开接口,任何人都可以调用,我就是把接口通过易语言实现了批量生成的功能效果。界面图:  WXID添加效果,不是微信号,是......
  • 单调队列优化多重背包
    多重背包题目已经很熟了我们要把它优化到O(nm)也就是对于每一个物品,我们只能够对dp数组进行一次遍历,并且不能枚举取几个物品或者说是,要在每一个状态下O(1)的找到取不同数量物品的最优解,并转移我们可以发现,其实转移的区间是非常有规律的,f[j]只能够从f[j-v[i]],f[j-2*v[i]]....f[j-c[i]*v......
  • 辨析二维对称矩阵压缩存储
    一、从0开始的二维数组1.如果压缩成上三角,则i,j对换即可。二、从1开始的二维数组2.如果压缩成上三角,则i,j对换即可。三、总结因此做题时一定要,先考虑二维数组与一维数组是从0还是从1开始。再考虑是下三角储存还是上三角存储,因此有四种可能性。根据选项一一排除即......
  • 在线微信wxid二维码生成器,转换微信号加好友工具接口,调用微信内部接口
    我声明一下,这个接口微信本身就存在的,并非是我逆向微信或者是HOOK微信,是正规的接口,任何人都能用,通过WXID直接添加对方好友,然后我就用易语言调用了一下接口而已,正规合规的哈,然后下面是框架和效果图以及完整代码。框架设计图:  下面是我示范的效果图,通过微信接口转换后转到名......
  • wxid转二维码在线生成器,加微信号好友接口工具,易语言源码分享
    用易语言开发的,我确保能用的,发布时间为11月20号,客户之前定制的我现在留着也没用,并且这个接口微信本身就有,我调用也不算是违规,然后下面是框架图和代码。框架图:  演示的图,通过WXID可以转到个人名片上面:【微信正规接口并非HOOK逆向】  易语言源码分享:=================......
  • 微信wxid转换二维码微信号加好友工具,自动批量转码器免费分享,开源版哈收藏!
    wxid估计很多小伙伴都知道,就是属于那种没有设置了微信号的账号,它没有设置自己的微信号或者就显示了默认的ID值,这个ID值你是没办法通过微信的好友添加框去添加的,但是有一种办法可以实现这种效果,只需要用软件,安卓手机或者电脑都可以我这里分享的是电脑的源码,目前是2023年11月20号,这......
  • 进程间通信的方式之消息队列和共享内存
    消息队列消息队列就是保存在内核中的消息链表,包括Posix消息队列和SystemV消息队列。有足够权限的进程可以向队列中添加消息,被赋予读权限的进程则可以读走队列中的消息。消息队列克服了信号承载信息量少,管道只能承载无格式字节流以及缓冲区大小受限等缺点。共享内存共享内存的机制,......
  • 代码随想录算法训练营第十天 | ● 理论基础 ● 232.用栈实现队列 ● 225. 用队列实现
    今日学习的文章链接和视频链接https://programmercarl.com/栈与队列理论基础.html●232.用栈实现队列varMyQueue=function(){this.stackIn=[];this.stackOut=[]};/***@param{number}x*@return{void}*/MyQueue.prototype.push=funct......
  • 【231119-1】如图,在正方形ABCD中,以AB为腰向正方形内部作等腰三角线ABE,点G在CD上,且CG=3
    【题目】如图,在正方形ABCD中,以AB为腰向正方形内部作等腰三角线ABE,点G在CD上,且CG=3DG,链接BG并延长,与AE交于F,与AD延长线交于H。连接DE交BH于点K,连接CK。若AE^2=BFBH,FG=13/5根号5.求:四边形EFKC的面积?【解答】......