Description
有一个a*b的整数组成的矩阵,现请你从中找出一个n*n的正方形区域,使得该区域所有数中的最大值和最小值
的差最小。
Input
第一行为3个整数,分别表示a,b,n的值第二行至第a+1行每行为b个非负整数,表示矩阵中相应位置上的数。每
行相邻两数之间用一空格分隔。
100%的数据2<=a,b<=1000,n<=a,n<=b,n<=1000
Output
仅一个整数,为a*b矩阵中所有“n*n正方形区域中的最大整数和最小整数的差值”的最小值。
题解:
普及的题目。。。
就是单调队列,用单调队列横向纵向分别求一下min和max就可以了。
然而top打成tail,Wa了许多遍,太丢人啦。
代码:
#include<bits/stdc++.h>
using namespace std;
inline int read(){
int x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=(x<<)+(x<<)+ch-'';ch=getchar();}
return x*f;
}
#define MN 1005
#define inf 1e12
int a,b,n,mp[MN][MN],ans;
pair<int,int>q[MN];
int top,tail,xmax[MN][MN],xmin[MN][MN];
int ma[MN][MN],mi[MN][MN];
void init(){top=;tail=;}
void get(int x){while(tail<=top&&q[tail].second<=x-n) tail++;}
bool pd(int x,int y,int k){if(x<y) return k;if(x>y) return k^;return true;}
void ins(int x,int y,bool k){
while(tail<=top&&pd(q[top].first,x,k)) top--;
q[++top]=make_pair(x,y);
}
int main(){
a=read(),b=read(),n=read();
register int i,j;
for(i=;i<=a;i++) for(j=;j<=b;j++) mp[i][j]=read();
for(i=;i<=a;i++){
init();
for(j=;j<=b;j++){
get(j);
ins(mp[i][j],j,);
xmax[i][j]=q[tail].first;
}
init();
for(j=;j<=b;j++){
get(j);
ins(mp[i][j],j,);
xmin[i][j]=q[tail].first;
}
}
for(j=;j<=b;j++){
init();
for(i=;i<=a;i++){
get(i);
ins(xmax[i][j],i,);
ma[i][j]=q[tail].first;
}
init();
for(i=;i<=a;i++){
get(i);
ins(xmin[i][j],i,);
mi[i][j]=q[tail].first;
}
}
ans=inf;
for(i=n;i<=a;i++)for(j=n;j<=b;j++) ans=min(ans,ma[i][j]-mi[i][j]);
printf("%d\n",ans);
return ;
}
来自PaperCloud的博客,未经允许,请勿转载,TKS