【简●解】[HAOI2007] 理想的正方形

【题目大意】#

有一个ab的整数组成的矩阵,现请你从中找出一个nn的正方形区域,使得该区域所有数中的最大值和最小值的差最小。

【分析】#

在暴力中想到优化,模仿曾经求二维前缀和的做法,先在每行求区间长度为n的最大值和最小值,再在此基础上求列上的最大值和最小值,则求得的即为单个nn正方形矩阵中的最大值和最小值。(仔细体味下)

用单调队列就可以搞定,和滑动窗口类似。

【Code】#

一个挣扎在英语一线的苦逼Oier。。。敲代码背单词。。。

Copy
#include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> #define ll long long using namespace std; const int N = 1000 + 5; const int INF = 0x7fffffff; inline int read(){ int f = 1, x = 0;char ch; do { ch = getchar(); if (ch == '-') f = -1; } while (ch < '0'||ch>'9'); do {x = x*10+ch-'0'; ch = getchar(); } while (ch >= '0' && ch <= '9'); return f*x; } int a, b, n, aa, bb, maps[N][N], ans = INF; int shallow[N][N];// 肤浅的 adj. ---X最大值 int reform[N][N];// 改革,改进 v. ---X最小值 int allergic[N][N];// 敏感的 adj. ---Y最大值 int association[N][N];//协会,交往 n. ---Y最小值 int violence[20 * N];// 暴力行为 adj. ---队列 int head = 1, tail = 0; int main(){ a = read(), b = read(), n = read(); for (int i = 1;i <= a; ++i) { for (int j = 1;j <= b; ++j) { maps[i][j] = read(); } } aa = a - n + 1; bb = b - n + 1; for (int i = 1;i <= a; ++i) { head = 1, tail = 0; // printf("rand %d : %d - %d \n", i, head, tail) ; for (int j = 1;j <= b; ++j) { while (maps[i][violence[tail]] <= maps[i][j] && head <= tail) tail--; violence[++tail] = j; while (head <= tail && violence[head] < j - n + 1) { head++; } shallow[i][j] = maps[i][violence[head]]; } } for (int i = 1;i <= a; ++i) { head = 1, tail = 0; // printf("rand %d : %d - %d \n", i, head, tail) ; for (int j = 1;j <= b; ++j) { while (maps[i][violence[tail]] >= maps[i][j] && head <= tail) tail--; violence[++tail] = j; while (head <= tail && violence[head] < j - n + 1) { head++; } reform[i][j] = maps[i][violence[head]]; } } // puts(""); // for (int i = 1;i <= a; ++i) { // for (int j = 1; j <= b; ++j) { // printf("%d ", reform[i][j]); // } // puts(""); // } for (int j = 1;j <= b; ++j) { head = 1, tail = 0; for (int i = 1;i <= a; ++i) { while (shallow[violence[tail]][j] <= shallow[i][j] && head <= tail) tail--; violence[++tail] = i; while (head <= tail && violence[head] < i - n + 1) { head++; } allergic[i][j] = shallow[violence[head]][j]; } } // puts(""); // for (int i = 1;i <= a; ++i) { // for (int j = 1; j <= b; ++j) { // printf("%d ", allergic[i][j]); // } // puts(""); // } for (int j = 1;j <= b; ++j) { head = 1, tail = 0; for (int i = 1;i <= a; ++i) { while (reform[violence[tail]][j] >= reform[i][j] && head <= tail) tail--; violence[++tail] = i; while (head <= tail && violence[head] < i - n + 1) { head++; } association[i][j] = reform[violence[head]][j]; } } // puts(""); // for (int i = 1;i <= a; ++i) { // for (int j = 1; j <= b; ++j) { // printf("%d ", association[i][j]); // } // puts(""); // } for (int i = n; i <= a; ++i) { for (int j = n; j <= b; ++j) { ans = min(ans, allergic[i][j] - association[i][j]); } } printf("%d", ans); return 0; }
posted @   SilentEAG  阅读(174)  评论(0编辑  收藏  举报
编辑推荐:
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示
CONTENTS