1604:理想的正方形
// 1604:理想的正方形.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
#include <deque>
#include <algorithm>
using namespace std;
/*
https://loj.ac/p/10182
http://ybt.ssoier.cn:8088/problem_show.php?pid=1604
原题来自:HAOI 2007
有一个 a×b
的整数组成的矩阵,现请你从中找出一个 n×n
的正方形区域,使得该区域所有数中的最大值和最小值的差最小。
【输入】
第一行为三个整数,分别表示 a,b,n
的值;
第二行至第 a+1
行每行为 b
个非负整数,表示矩阵中相应位置上的数。
【输出】
输出仅一个整数,为 a×b
矩阵中所有「n×n
正方形区域中的最大整数和最小整数的差值」的最小值。
【输入样例】
5 4 2
1 2 5 6
0 17 16 0
16 17 2 1
2 10 2 1
1 2 2 2
【输出样例】
1
2≤a,b≤1000,n≤a,n≤b,n≤100,矩阵中的所有数都不超过 10^9。
*/
const int N = 1010;
long long arr[N][N];
long long minrow[N][N];
long long maxrow[N][N];
int a, b, n;
void getmin(int row) {
deque<long long> q;
for (int i = 1; i <= b; i++) {
while (!q.empty() && i - q.front() + 1 > n) q.pop_front();
while (!q.empty() && arr[row][q.back()] >= arr[row][i]) q.pop_back();
if (q.empty() || arr[row][q.front()] >= arr[row][i]) {
minrow[row][i] = arr[row][i];
}
else {
minrow[row][i] = arr[row][q.front()];
}
q.push_back(i);
}
}
void getmax(int row) {
deque<long long> q;
for (int i = 1; i <= b; i++) {
while (!q.empty() && i - q.front() + 1 > n) q.pop_front();
while (!q.empty() && arr[row][q.back()] <= arr[row][i]) q.pop_back();
if (q.empty() || arr[row][q.front()] <= arr[row][i]) {
maxrow[row][i] = arr[row][i];
}
else {
maxrow[row][i] = arr[row][q.front()];
}
q.push_back(i);
}
}
void getminCol(int col,int mincol[]) {
deque<long long> q;
for (int i = 1; i <= a; i++) {
while (!q.empty() && i - q.front() + 1 > n) q.pop_front();
while (!q.empty() && minrow[q.back()][col] >= minrow[i][col]) q.pop_back();
if (q.empty() || minrow[q.front()][col] >= minrow[i][col]) {
mincol[i] = minrow[i][col];
}
else {
mincol[i] = minrow[q.front()][col];
}
q.push_back(i);
}
}
void getmaxCol(int col, int maxcol[]) {
deque<long long> q;
for (int i = 1; i <= a; i++) {
while (!q.empty() && i - q.front() + 1 > n) q.pop_front();
while (!q.empty() && maxrow[q.back()][col] <= maxrow[i][col]) q.pop_back();
if (q.empty() || maxrow[q.front()][col] <= maxrow[i][col]) {
maxcol[i] = maxrow[i][col];
}
else {
maxcol[i] = maxrow[q.front()][col];
}
q.push_back(i);
}
}
int main()
{
cin >> a >> b >> n;
for (int i = 1; i <= a; i++) {
for (int j = 1; j <= b; j++) {
cin >> arr[i][j];
}
}
for (int i = 1; i <= a; i++) {
getmin(i);
getmax(i);
}
long long ans = 1e18;
for (int i = n; i <= b; i++) {
//对每个竖列做滑动窗口 得到最大最小值
int mincol[N]; int maxcol[N];
getminCol(i, mincol);
getmaxCol(i, maxcol);
for (int j = n; j <= a; j++) {
ans = min(ans, 1ll * maxcol[j] - mincol[j]);
}
}
cout << ans << endl;
return 0;
}
作 者: itdef
欢迎转帖 请保持文本完整并注明出处
技术博客 http://www.cnblogs.com/itdef/
B站算法视频题解
https://space.bilibili.com/18508846
qq 151435887
gitee https://gitee.com/def/
欢迎c c++ 算法爱好者 windows驱动爱好者 服务器程序员沟通交流
如果觉得不错,欢迎点赞,你的鼓励就是我的动力
欢迎转帖 请保持文本完整并注明出处
技术博客 http://www.cnblogs.com/itdef/
B站算法视频题解
https://space.bilibili.com/18508846
qq 151435887
gitee https://gitee.com/def/
欢迎c c++ 算法爱好者 windows驱动爱好者 服务器程序员沟通交流
如果觉得不错,欢迎点赞,你的鼓励就是我的动力


【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
2020-06-17 poj 1251 丛林中的道路 最小生成树
2020-06-17 poj 1861 Network 最小生成树 模板