蓝桥杯刷题-13-子矩阵-二维滑动窗口 ಥ_ಥ

给定一个 n × m (n 行 m 列)的矩阵。

设一个矩阵的价值为其所有数中的最大值和最小值的乘积。求给定矩阵的所有大小为 a × b (a 行 b 列)的子矩阵的价值的和。

答案可能很大,你只需要输出答案对 998244353 取模后的结果。

cpp 复制代码
//四层for循环
for(){//行n
	for(){//列m
		for(){//a
			for(){//b
			}
		}
	}

}


cpp 复制代码
//二维单调队列
#include<bits/stdc++.h>
#define endl '\n'
#define deb(x) cout << #x << " = " << x << '\n';
#define INF 0x3f3f3f3f
#define int long long
using namespace std;
const int mod =  998244353;
const int N = 1e3 + 10;
int g[N][N];
int q[N];
int line_max[N][N], line_min[N][N];
int maxv[N][N], minv[N][N];
int a, b, n, m;

void solve()
{
	cin >> n >> m >> a >> b;
	for(int i = 0; i < n; i ++)
		for(int j = 0; j < m; j ++)
			cin >> g[i][j];

	//求出每一行的滑动窗口
	for(int i = 0; i < n; i ++){
		int h = 0, t = -1;
		for(int j = 0; j < m; j ++){

			if(h <= t and q[h] < j - b + 1){
				h ++;
			}
			while(h <= t and g[i][q[t]] <= g[i][j])
				t--;

			q[++t] = j;
			if(j - b + 1 >= 0){
				line_max[i][j - b + 1] = g[i][q[h]];
			}
		}
	}
	
	//对每一行的滑动窗口求一遍滑动窗口
	for(int j = 0; j < m; j ++){
		int h = 0, t = -1;
		for(int i = 0; i < n; i ++){
			if(h <= t and q[h] < i - a + 1){
				h ++;
			}
			while(h <= t and line_max[q[t]][j] <= line_max[i][j])
				t --;
			
			q[++t] = i;
			if(i - a + 1 >= 0)
				maxv[i - a + 1][j] = line_max[q[h]][j];
		}
	}



	//求最小值
	//先针对每一行,求出每一行的滑动窗口。
	for(int i = 0; i < n; i ++){
		int h = 0, t = -1;
		for(int j = 0; j < m; j ++){
			if(h <= t and q[h] < j - b + 1){
				h ++;
			}
			while(h <= t and g[i][q[t]] >= g[i][j])
				t --;
			q[++ t] = j;
			if(j - b + 1 >= 0)
				line_min[i][j - b + 1] = g[i][q[h]]; 
		}
	}


	//针对每一列的滑动黑窗口,求滑动窗口。
	for(int j = 0; j < m; j ++){
		int h = 0, t = -1;
		for(int i = 0; i < n; i ++){
			if(h <= t and q[h] < i - a + 1){
				h ++;
			}
			while(h <= t and line_min[q[t]][j] >= line_min[i][j])
				t --;
			q[++ t] = i;
			if(i - a + 1 >= 0)
				minv[i - a + 1][j] = line_min[q[h]][j];
		}
	}

	int ans = 0;
	for(int i = 0; i < n; i ++){
		for(int j = 0; j < m; j ++){
			ans = (ans + maxv[i][j] * minv[i][j] % mod) % mod;
		}
	}
	cout << ans << endl;

}

signed main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	int t;
	t = 1;
	//cin >> t;
	while(t--)
	solve();
}
相关推荐
阿巴~阿巴~6 小时前
C/C++蓝桥杯算法真题打卡(Day3)
c语言·c++·算法·蓝桥杯
<但凡.6 小时前
题海拾贝:P9241 [蓝桥杯 2023 省 B] 飞机降落
数据结构·算法·蓝桥杯
Spring小子6 小时前
蓝桥杯[每日两题] 真题:好数 神奇闹钟 (java版)
java·数据结构·算法·蓝桥杯
EnigmaCoder7 小时前
蓝桥杯刷题周计划(第二周)
学习·算法·蓝桥杯
焦糖码奇朵、10 小时前
Matlab:矩阵运算篇——矩阵数学运算
人工智能·matlab·矩阵·信息与通信
痛&快乐着19 小时前
线性代数之矩阵特征值与特征向量的数值求解方法
线性代数·矩阵
余~~185381628001 天前
碰一碰发视频系统之写卡功能开发了,支持OEM
线性代数·矩阵·音视频
ChoSeitaku1 天前
NO.30十六届蓝桥杯备战|C++输入输出|单组测试用例|多组测试用例|isalpha|逗号表达式(C++)
c++·蓝桥杯·测试用例
阿巴~阿巴~1 天前
C/C++蓝桥杯算法真题打卡(Day4)
数据结构·c++·算法·蓝桥杯
被制作时长两年半的个人练习生1 天前
【算法】矩阵置零
线性代数·算法·矩阵