欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

【单调】理想的正方形

程序员文章站 2022-06-05 13:47:15
...

luoguP2216
【HAOI2007】
题目:有一个ab的整数组成的矩阵,现请你从中找出一个nn的正方形区域,使得该区域所有数中的最大值和最小值的差最小。
题解:二维滑动窗口
一维是维护i结尾的最值,二维就是维护一维维护后的最值。
垃圾图解:
【单调】理想的正方形

#include<bits/stdc++.h>
using namespace std;
const int N=1e3+10,K=1e2;
int n,m,k;
int a[N][N],ma[N][N],mi[N][N];
int z[N],c[N];
int p1,p2,q1,q2;
int f1[N][N],f2[N][N];
int g1[N][N],g2[N][N];
void clean()
{
	memset(z,0,sizeof(z));
	memset(c,0,sizeof(c));
	p1=1;p2=0;q1=1;q2=0;	
}
int main()
{
	scanf("%d%d%d",&n,&m,&k);
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			scanf("%d",&a[i][j]);
	for(int i=1;i<=n;i++)
	{
		clean();
		for(int j=1;j<=m;j++)
		{
			while(p1<=p2&&j-z[p1]>=k)p1++;
			while(q1<=q2&&j-c[q1]>=k)q1++;
			while(p1<=p2&&a[i][z[p2]]>a[i][j])p2--;//<
			while(q1<=q2&&a[i][c[q2]]<a[i][j])q2--;//>
			z[++p2]=j;c[++q2]=j;
			f1[i][j]=a[i][z[p1]];
			f2[i][j]=a[i][c[q1]];
		//for(int k=p1;k<=p2;k++)printf("(%2d,%2d)",i,z[k]);
		}
	}
	for(int j=1;j<=m;j++)
	{
		clean();
		for(int i=1;i<=n;i++)
		{
			while(p1<=p2&&i-z[p1]>=k)p1++;
			while(q1<=q2&&i-c[q1]>=k)q1++;
			while(p1<=p2&&f1[z[p2]][j]>f1[i][j])p2--;//<
			while(q1<=q2&&f2[c[q2]][j]<f2[i][j])q2--;//>
			z[++p2]=i;c[++q2]=i;
			g1[i][j]=f1[z[p1]][j];
			g2[i][j]=f2[c[q1]][j];
		}
	}
	int ans=1e9;
	for(int i=k;i<=n;i++)
		for(int j=k;j<=m;j++)
			ans=min(ans,g2[i][j]-g1[i][j]);
	printf("%d",ans);
}
相关标签: 入门