首页 > 其他分享 >洛谷题单指南-常见优化技巧-P2216 [HAOI2007] 理想的正方形

洛谷题单指南-常见优化技巧-P2216 [HAOI2007] 理想的正方形

时间:2024-09-03 11:27:33浏览次数:13  
标签:窗口 正方形 int 洛谷题 最大值 HAOI2007 ++ 最小值 P2216

原题链接:https://www.luogu.com.cn/problem/P2216

题意解读:在矩阵中找n*n正方形里最大值和最小值差值的最小值。

解题思路:

1、枚举法

直接枚举所有n*n的正方形的位置,然后在遍历求最大值、最小值,复杂度为O(n^4),显然不能通过。

2、二维单调队列

既然是求正方形范围内的最值,看起来是二维,其实可以转化为一维,过程如下:

一、先求n*n正方形范围的最大值:

第一步:按行处理,计算每行滑动窗口长度是n范围的最大值

第二步:按列处理,计算每列滑动窗口长度是n范围的最大值

二、再求n*n正方形范围的最小值

第一步:按行处理,计算每行滑动窗口长度是n范围的最小值

第二步:按列处理,计算每列滑动窗口长度是n范围的最小值

三、对上述过程计算求得的所有最大值、最小值对应的进行相减,取最小值,结果为1。

因此,该过程涉及4次单调队列求最值的应用。

100分代码:

#include <bits/stdc++.h>
using namespace std;

const int N = 1005;

int a, b, n;
int w[N][N];
int xmax[N][N], xymax[N][N]; //行窗口最大值,列窗口最大值
int xmin[N][N], xymin[N][N]; //行窗口最小值,列窗口最小值
int q[N], l = 0, r = -1;

int main()
{
    cin >> a >> b >> n;
    for(int i = 1; i <= a; i++)
    {
        for(int j = 1; j <= b; j++)
        {
            cin >> w[i][j];
        }
    }

    for(int i = 1; i <= a; i++)
    {
        l = 0, r = -1;
        for(int j = 1; j <= b; j++)
        {
            while(l <= r && j - q[l] + 1 > n) l++;
            while(l <= r && w[i][j] > w[i][q[r]]) r--;
            q[++r] = j;
            if(j >= n) xmax[i][j - n + 1] = w[i][q[l]];
        }
    }
    
    for(int i = 1; i <= b - n + 1; i++)
    {
        l = 0, r = -1;
        for(int j = 1; j <= a; j++)
        {
            while(l <= r && j - q[l] + 1 > n) l++;
            while(l <= r && xmax[j][i] > xmax[q[r]][i]) r--;
            q[++r] = j;
            if(j >= n) xymax[j - n + 1][i] = xmax[q[l]][i];
        }
    }

    for(int i = 1; i <= a; i++)
    {
        l = 0, r = -1;
        for(int j = 1; j <= b; j++)
        {
            while(l <= r && j - q[l] + 1 > n) l++;
            while(l <= r && w[i][j] < w[i][q[r]]) r--;
            q[++r] = j;
            if(j >= n) xmin[i][j - n + 1] = w[i][q[l]];
        }
    }
    
    for(int i = 1; i <= b - n + 1; i++)
    {
        l = 0, r = -1;
        for(int j = 1; j <= a; j++)
        {
            while(l <= r && j - q[l] + 1 > n) l++;
            while(l <= r && xmin[j][i] < xmin[q[r]][i]) r--;
            q[++r] = j;
            if(j >= n) xymin[j - n + 1][i] = xmin[q[l]][i];
        }
    }

    int ans = 2e9;
    for(int i = 1; i <= a - n + 1; i++)
    {
        for(int j = 1; j <= b - n + 1; j++)
        {
            ans = min(ans, xymax[i][j] - xymin[i][j]);
        }
    }
    cout << ans;

    return 0;
}

 

标签:窗口,正方形,int,洛谷题,最大值,HAOI2007,++,最小值,P2216
From: https://www.cnblogs.com/jcwy/p/18394204

相关文章

  • 洛谷题单指南-常见优化技巧-P2032 扫描
    原题链接:https://www.luogu.com.cn/problem/P2032题意解读:求滑动窗口内的最大值,典型的单调队列应用。解题思路:单调队列的三部曲:1、去头。已存入的元素个数超过k,则去头。注意队列里存的是元素下标,只需要用当前下标减去队头元素来判断即可。2、去尾。根据单调队列的单调性,如果......
  • 洛谷题单指南-常见优化技巧-P1950 长方形
    原题链接:https://www.luogu.com.cn/problem/P1950题意解读:在一张n*m个格子的纸上,从没有画过的格子中剪出长方形的方案数。解题思路:1、暴力做法枚举所有的子矩阵O(n^4),然后用二维前缀和计算子矩阵的和,通过和来判断子矩阵是否全部是'.'。2、优化做法针对每一行进行处理,计算包......
  • 洛谷题单指南-常见优化技巧-P2866 [USACO06NOV] Bad Hair Day S
    原题链接:https://www.luogu.com.cn/problem/P2866题意解读:每个牛能看到的右边比他矮的牛,直到有比他高的挡住为止,因此只用找每个牛右边第一个比他高的牛的位置即可计算中间比他矮的有多少。解题思路:典型的单调栈应用,注意,常规的单调栈可以用来:1、找每个数左边第一个比他小的数的......
  • 洛谷题单指南-常见优化技巧-P4147 玉蟾宫
    原题链接:https://www.luogu.com.cn/problem/P4147题意解读:找到一个只包含'F'的最大的子矩形。解题思路:方法1:设R为0,F为1,先计算二维前缀和,再枚举所有子矩形左上角(x1,y1)、右下角(x2,y2),计算子矩形的区间和,更新最大值,只能得到部分分。方法2:对于二维矩阵每个点,定义三个属性:h[][]......
  • 洛谷题单指南-常见优化技巧-P1115 最大子段和
    原题链接:https://www.luogu.com.cn/problem/P1115题意解读:最大连续子序列的和。解题思路:DP的做法可参考:https://www.cnblogs.com/jcwy/p/18144124也可以采用双指针来枚举:i从1开始,j=i用j来枚举连续序列,如果已有序列和+下一个a[j]>=下一个a[j],那个j一直++,累加序列和如果出......
  • 洛谷题单指南-常见优化技巧-P1638 逛画展
    原题链接:https://www.luogu.com.cn/problem/P1638题意解读:在n个数中,选出a、b两个端点,使得a~b之间不同的数字为m,且b-a最小。解题思路:要寻找最小的包括所有数字的区间,可以采用双指针算法1、设i,j分别是左右指针2、如果当前区间内不同数字个数不到m,j往后移3、记录数字个数到m时......
  • 洛谷题单指南-前缀和差分与离散化-P1904 天际线
    原题链接:https://www.luogu.com.cn/problem/P1904题意解读:给出(左端点,高度,右端点)表示的若干建筑,要输出其轮廓,所谓轮廓就是每个点被覆盖的最高建筑的高度所描绘的线。解题思路:如果能计算每个点被覆盖的最高建筑的高度,用数组h[10005]保存,那么输出轮廓的过程只需要枚举每一个点,如......
  • 洛谷题单指南-前缀和差分与离散化-P3029 [USACO11NOV] Cow Lineup S
    原题链接:https://www.luogu.com.cn/problem/P3029题意解读:不同的坐标位置有不同种类的牛,要计算一个最小的区间,包括所有种类的牛。解题思路:由于坐标位置不连续,并且数值范围较大,因此需要离散化处理,将坐标处理成1~n连续分布由于种类编号数值范围也比较大,也需要离散化处理,去重后的......
  • 洛谷题单指南-前缀和差分与离散化-P4552 [Poetize6] IncDec Sequence
    原题链接:https://www.luogu.com.cn/problem/P4552题意解读:对一组数字序列,进行若干次区间+1或者-1操作,最终使得所有数字一样,计算最少的操作次数,以及能得到多少种不同序列。解题思路:要使得序列每一个数字都相同,则其差分除了第一项之外其余项都是0。因此,问题转化为:给定一个差分数......
  • 洛谷题单指南-前缀和差分与离散化-P2882 [USACO07MAR] Face The Right Way G
    原题链接:https://www.luogu.com.cn/problem/P2882题意解读:一个有F、B组成的序列,每次可以翻转k个连续子序列,翻转:F->B,B->F,计算最少翻转多少次可以将序列都变成F,并求相应的k。解题思路:为方便处理,设F为1,B为01、朴素做法枚举k:1~n  枚举序列,一旦遇到0,就将连续k个字符翻转,如果可......