亳州市网站建设_网站建设公司_百度智能云_seo优化
2026/1/17 2:30:13 网站建设 项目流程

P2216 [HAOI2007] 理想的正方形

时间限制: 1.00s 内存限制: 128.00MB

复制 Markdown

中文

退出 IDE 模式

题目描述

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

输入格式

第一行为 3 个整数,分别表示 a,b,n 的值。

第二行至第 a+1 行每行为 b 个非负整数,表示矩阵中相应位置上的数。每行相邻两数之间用一空格分隔。

输出格式

仅一个整数,为 a×b 矩阵中所有“ n×n 正方形区域中的最大整数和最小整数的差值”的最小值。

输入输出样例

输入 #1复制运行

5 4 2 1 2 5 6 0 17 16 0 16 17 2 1 2 10 2 1 1 2 2 2

输出 #1复制运行

1

说明/提示

矩阵中的所有数都不超过 1,000,000,000。

20% 的数据 2≤a,b≤100,n≤a,n≤b,n≤10。

100% 的数据 2≤a,b≤1000,n≤a,n≤b,n≤100。

先进行一维的单调队列然后将一维的结果再次进行单调队列即可

#include <bits/stdc++.h> using namespace std; const int N=1e3+5; int a[N][N]; int cmax[N][N],cmin[N][N]; int q1[N],q2[N]; int n,m,len; int main() { ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); cin>>n>>m>>len; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++)cin>>a[i][j]; for(int i=1;i<=n;i++){ int l1=1,l2=1,r1=0,r2=0; for(int j=1;j<=m;j++){ while(l1<=r1&&j-q1[l1]>=len)l1++; while(l2<=r2&&j-q2[l2]>=len)l2++; while(l1<=r1&&a[i][j]>=a[i][q1[r1]])r1--; while(l2<=r2&&a[i][j]<=a[i][q2[r2]])r2--; q1[++r1]=j;q2[++r2]=j; cmax[i][j]=a[i][q1[l1]];cmin[i][j]=a[i][q2[l2]]; } } int ans=INT_MAX; for(int j=len;j<=m;j++){ int l1=1,l2=1,r1=0,r2=0; for(int i=1;i<=n;i++){ while(l1<=r1&&i-q1[l1]>=len)l1++; while(l2<=r2&&i-q2[l2]>=len)l2++; while(l1<=r1&&cmax[i][j]>=cmax[q1[r1]][j])r1--; while(l2<=r2&&cmin[i][j]<=cmin[q2[r2]][j])r2--; q1[++r1]=i;q2[++r2]=i; if(i>=len)ans=min(ans,cmax[q1[l1]][j]-cmin[q2[l2]][j]); } } cout<<ans<<'\n'; return 0; }

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询