首页 > 编程语言 >用 滑动窗口 算法 解决 蓝桥杯子矩阵 的运行超时 问题

用 滑动窗口 算法 解决 蓝桥杯子矩阵 的运行超时 问题

时间:2024-03-19 16:31:32浏览次数:18  
标签:MIN int MAX 矩阵 蓝桥 ++ vector front 超时


这题如果用暴力算法解决,会用到四个for循环。当数据很大时,会超时,无法通过蓝桥杯。

如果掌握了二维滑动窗口,会让时间复杂度减少俩个数量级,很好地解决超时的问题。

关于滑动窗口算法,如果读者不会的话,建议去哔站看大佬的讲解视频,笔者也是昨天才学的。

如果已经会了滑动窗口算法,我觉得用deque类定义单调队列比较适合,优化了代码的效率,敲起来也方便了许多。

关于deque的相关知识,在CSDN搜索相关文章了解即可,同样,笔者也是才学的。

非常好用!


#include<bits/stdc++.h>
using namespace std;
int main()
{
    //输入
    int n, m, a, b, ans = 0;
    cin >> n >> m >> a >> b;
    deque < int > Q;
    //J --矩阵,,MIN--最小值,,MAX--最大值,,MIN_n--n行最小值,,MAX_n--n行最大值
    vector < vector<int> >J(n, vector<int>(m));
    vector < vector<int> >MIN_n(n, vector<int>(m - b + 1));
    vector < vector<int> >MIN(n - a + 1, vector<int>(m - b + 1));
    vector < vector<int> >MAX_n(n, vector<int>(m - b + 1));
    vector < vector<int> >MAX(n - a + 1, vector<int>(m - b + 1));
    for (int i = 0; i < n; i++)
        for (int j = 0; j < m; j++)
            cin >> J[i][j];
    //构造MIN_n和MAX_n
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            if (!Q.empty() && j - Q.front() + 1 > b) Q.pop_front();//队列中有元素且滑动窗口的大小超过了b,则出队
            while (!Q.empty() && J[i][Q.back()] >= J[i][j]) Q.pop_back();//如果进队元素破坏了队列单调性,则r--
            Q.emplace_back(j);//正常进队
            if (j >= b - 1) MIN_n[i][j - b + 1] = J[i][Q.front()];//提取出最小值
        }
        Q.clear();
        for (int j = 0; j < m; j++) {
            if (!Q.empty() && j - Q.front() + 1 > b) Q.pop_front();
            while (!Q.empty() && J[i][Q.back()] <= J[i][j]) Q.pop_back();
            Q.emplace_back(j);
            if (j >= b - 1) MAX_n[i][j - b + 1] = J[i][Q.front()];
        }
        Q.clear();
    }
    //构造MIN和MAX
    for (int i = 0; i < m - b + 1; i++) {
        for (int j = 0; j < n; j++) {
            if (!Q.empty() && j - Q.front() + 1 > a) Q.pop_front();
            while (!Q.empty() && MIN_n[Q.back()][i] >= MIN_n[j][i]) Q.pop_back();
            Q.emplace_back(j);
            if (j >= a - 1) MIN[j - a + 1][i] = MIN_n[Q.front()][i];
        }
        Q.clear();
        for (int j = 0; j < n; j++) {
            if (!Q.empty() && j - Q.front() + 1 > a) Q.pop_front();
            while (!Q.empty() && MAX_n[Q.back()][i] <= MAX_n[j][i]) Q.pop_back();
            Q.emplace_back(j);
            if (j >= a - 1) MAX[j - a + 1][i] = MAX_n[Q.front()][i];
        }
        Q.clear();
    }
    //计算价值和
    for (int i = 0; i < n - a + 1; i++)
        for (int j = 0; j < m - b + 1; j++)
            ans += MIN[i][j] * MAX[i][j];
    cout << ans % 998244353;
    return 0;
}

标签:MIN,int,MAX,矩阵,蓝桥,++,vector,front,超时
From: https://blog.csdn.net/2401_82949509/article/details/136812565

相关文章

  • P8685 [蓝桥杯 2019 省 A] 外卖店优先级
    这道题虽然难度很低,但是细节不少1.要先处理减,再处理加。因为是先经历了空档期的优先级衰减,然后才有订单带来的优先级提升;先减后加的时候有0这个下限兜底,如果先加后减可能会导致答案偏小。2.减之后和加之后都要check一下,如果in_cache为true,减完之后小于等于三,但是加了以后又上升......
  • cuda从入门到精通(六)共享内存和循环分块实现CUDA矩阵乘
    本文系转载,出处:https://mp.weixin.qq.com/s/1w1WFPoUEvVECsurqmvJDw在CUDA编程中,共享内存和循环分块(looptiling)是两种常见的优化策略,它们可以帮助我们提高矩阵乘法的性能。共享内存(SharedMemory):在GPU中,每个线程块(block)都有自己的共享内存。与全局内存相比,共享内存的访问......
  • 2024 蓝桥打卡Day15
    洛谷刷题P8752[蓝桥杯2021省B2]特殊年份题目[P8752[蓝桥杯2021省B2]特殊年份](https://www.luogu.com.cn/problem/P8752)题解P8780[蓝桥杯2022省B]刷题统计题目[P8780[蓝桥杯2022省B]刷题统计](https://www.luogu.com.cn/problem/P8780)题解P......
  • 蓝桥杯刷题(十一)
    1.卡片反向思考,看k种卡片可以分给几位同学代码n=int(input())k=1whilek*(k+1)<2*n:k+=1print(k)2.美丽的2代码deff(x)->bool:whilex:ifx%10==2:returnTruex//=10returnFalsecnt=0foriinrange(1,2021):iff(i):......
  • P8626 [蓝桥杯 2015 省 A] 灾后重建
    根号分治之类的思路分析这里就不讲了,主要关注代码细节:#include<iostream>#include<stdio.h>#include<algorithm>#include<vector>#include<string>#include<cmath>#defineFor(i,j,n)for(inti=j;i<=n;++i)usingnamespacestd;co......
  • 蓝桥杯day4刷题日记
    P8605[蓝桥杯2013国AC]网络寻路思路来源于https://www.luogu.com.cn/article/iat8irsf#include<iostream>usingnamespacestd;intn,m;intq[10010];intv[100010],u[100010];longlongres;intmain(){ cin>>n>>m; for(inti=0;i<m;i++) { cin......
  • 蓝桥杯——344图书管理员
      法一使用取模运算对于每本书的图书编码(bookCode),我们需要判断其是否以读者的需求码结尾。首先,将需求码的长度作为指数,使用Math.pow(10,demandLength)来得到一个以需求码长度为指数的基数。然后,将书的图书编码与这个基数进行取模运算,即bookCode%Math.pow(10,demandLe......
  • 【LeetCode 2684】矩阵中移动的最大次数
    题目描述原题链接:2684矩阵中移动的最大次数解题思路每次只能向右侧的下一列紧挨着的三行严格大的格子移动;能移动到i列代表能移动i次,这取决于i-1列可到达的矩阵位置的状态,即可以整列递推相邻列是否可移动到达;两个方向递推的思路:三个(col+1)位置的状态可以逆推出一个(c......
  • 2023年蓝桥杯省赛——幸运数字
    目录题目链接:0幸运数字-蓝桥云课(lanqiao.cn)解法思路高级思路总结题目链接:0幸运数字-蓝桥云课(lanqiao.cn)解法首先是我写了差不多一个小时的解法,裂开了,为什么我如此废物思路        寻找第2023个在二进制、八进制、十进制和十六进制表示下都为哈......
  • 2023年蓝桥杯模拟省赛——列名
    目录题目链接:2.列名-蓝桥云课(lanqiao.cn)思路高级思路:进制转换难点一难点二难点三总结题目链接:2.列名-蓝桥云课(lanqiao.cn)思路先来看我的暴力的思路吧主要有以下步骤:初始化一个长度为3的数组res用于存放结果,并且定义一个变量 p 表示目前数组中的......