1047: [HAOI2007]理想的正方形
Time Limit: 10 Sec Memory Limit: 162 MB Submit: 3481 Solved: 1917 [Submit][Status][Discuss]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正方形区域中的最大整数和最小整数的差值”的最小值。
Sample Input
5 4 2
单调队列裸题
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<cstdlib> 5 #include<cmath> 6 #include<algorithm> 7 using namespace std; 8 int a,b,n; 9 int s[1001][1001]; 10 int maxi[1001][1001]; 11 int mini[1001][1001]; 12 int q[1001],w[1001],q1[1001],w1[1001]; 13 int main() 14 { 15 scanf("%d%d%d",&a,&b,&n); 16 for(int i=1;i<=a;i++) 17 for(int j=1;j<=b;j++)scanf("%d",&s[i][j]); 18 int head=0,tail=0,head1=0,tail1=0; 19 for(int i=1;i<=a;i++) 20 { 21 head=1,tail=0; 22 head1=1,tail1=0; 23 for(int j=1;j<=b;j++) 24 { 25 while(tail>=head&&s[i][j]>=q[tail]) tail--; 26 q[++tail]=s[i][j];w[tail]=j; 27 while(tail>=head&&w[head]<j-n+1) head++; 28 maxi[i][j]=q[head]; 29 while(tail1>=head1&&s[i][j]<=q1[tail1]) tail1--; 30 q1[++tail1]=s[i][j];w1[tail1]=j; 31 while(tail1>=head1&&w1[head1]<j-n+1) head1++; 32 mini[i][j]=q1[head1]; 33 } 34 } 35 for(int j=1;j<=b;j++) 36 { 37 head=1,tail=0; 38 head1=1,tail1=0; 39 for(int i=1;i<=a;i++) 40 { 41 while(tail>=head&&maxi[i][j]>=q[tail]) tail--; 42 q[++tail]=maxi[i][j];w[tail]=i; 43 while(tail>=head&&w[head]<i-n+1) head++; 44 maxi[i][j]=q[head]; 45 while(tail1>=head1&&mini[i][j]<=q1[tail1]) tail1--; 46 q1[++tail1]=mini[i][j];w1[tail1]=i; 47 while(tail1>=head1&&w1[head1]<i-n+1) head1++; 48 mini[i][j]=q1[head1]; 49 } 50 } 51 int ans=2147483647; 52 for(int i=n;i<=a;i++) 53 for(int j=n;j<=b;j++) ans=min(ans,maxi[i][j]-mini[i][j]); 54 cout<<ans; 55 }