列表

详情


NC20541. [HAOI2007]理想的正方形

描述

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

输入描述

第一行为3个整数,分别表示a,b,n的值
第二行至第a+1行每行为b个非负整数,表示矩阵中相应位置上的数。
每行相邻两数之间用一空格分隔。
100%的数据2 ≤ a,b ≤ 1000,n ≤ a,n ≤ b,n ≤ 1000

输出描述

仅一个整数,为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

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++(clang++11) 解法, 执行用时: 210ms, 内存消耗: 12180K, 提交时间: 2021-03-14 13:57:29

#include<bits/stdc++.h>
using namespace std;
const int NN=1004;
int g[NN][NN],maxn[NN][NN],minn[NN][NN],q1[NN],q2[NN];
int main()
{
	int a,b,n,ans=1e9,h1,h2,t1,t2;
	scanf("%d%d%d",&a,&b,&n);
	for(int i=1;i<=a;i++)
		for(int j=1;j<=b;j++)
			scanf("%d",&g[i][j]);
	for(int i=1;i<=a;i++)
	{
		h1=0;
		h2=0;
		t1=-1;
		t2=-1;
		for(int j=1;j<=b;j++)
		{
			if(h1<=t1&&q1[h1]<=j-n)
				h1++;
			if(h2<=t2&&q2[h2]<=j-n)
				h2++;
			while(h1<=t1&&g[i][q1[t1]]<=g[i][j])
				t1--;
			while(h2<=t2&&g[i][q2[t2]]>=g[i][j])
				t2--;
			q1[++t1]=q2[++t2]=j;
			if(h1<=t1&&j>=n)
				maxn[i][j-n+1]=g[i][q1[h1]];
			if(h2<=t2&&j>=n)
				minn[i][j-n+1]=g[i][q2[h2]];
		}
	}
	for(int i=1;i<=b-n+1;i++)
	{
		h1=0;
		h2=0;
		t1=-1;
		t2=-1;
		for(int j=1;j<=a;j++)
		{
			if(h1<=t1&&q1[h1]<=j-n)
				h1++;
			if(h2<=t2&&q2[h2]<=j-n)
				h2++;
			while(h1<=t1&&maxn[q1[t1]][i]<=maxn[j][i])
				t1--;
			while(h2<=t2&&minn[q2[t2]][i]>=minn[j][i])
				t2--;
			q1[++t1]=q2[++t2]=j;
			if(h1<=t1&&h2<=t2&&j>=n)
				ans=min(ans,maxn[q1[h1]][i]-minn[q2[h2]][i]);
		}
	}
	printf("%d",ans);
	return 0;
}

上一题