1047: [HAOI2007]理想的正方形

Description

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

Input

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

Output

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

Sample Input

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

Sample Output

1
 
考虑一下这个题目。。。行与行之间是独立的。。。
所以我们可以先求出每一行,然后在拓展到每一行。。。
用f[i][j]表示第j行i-n+1 到 i 的最大值,g[i][j]表示最小值。。。
然后我们会发现如果枚举会炸。。。所以想到队列优化。。。这样就可以做啦....
 1 #include<iostream>
 2 #include<cstdlib>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<cstdio>
 6 #include<algorithm>
 7 #include<string>
 8 #include<map>
 9 #include<queue>
10 #include<vector>
11 #include<set>
12 #define inf 1000000000
13 #define maxn 1000+5
14 #define maxm 1000+5
15 #define eps 1e-10
16 #define ll long long
17 #define for0(i,n) for(int i=0;i<=(n);i++)
18 #define for1(i,n) for(int i=1;i<=(n);i++)
19 #define for2(i,x,y) for(int i=(x);i<=(y);i++)
20 #define for3(i,x,y) for(int i=(x);i>=(y);i--)
21 #define for4(i,x) for(int i=head[x],y=e[i].go;i;i=e[i].next,y=e[i].go)
22 using namespace std;
23 int read(){
24     int x=0,f=1;char ch=getchar();
25     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
26     while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}
27     return x*f;
28 }
29 int a[maxn][maxm],f[maxn][maxm],g[maxn][maxm];
30 struct num{
31     int w,id;
32 }q[maxn];
33 int main(){
34     //freopen("input.txt","r",stdin);
35     //freopen("output.txt","w",stdout);
36     int t=read(),b=read(),n=read();
37     for1(i,t)
38         for1(j,b)
39             a[i][j]=read();
40     
41     for1(i,t){
42         int l=1,r=0;
43         for1(j,b){
44             while(q[r].w<=a[i][j]&&l<=r&&r)r--;
45             while(q[l].id<j-n+1&&l<=r&&l)l++;
46             q[++r].id=j;q[r].w=a[i][j];
47             f[i][j]=q[l].w;
48         }
49     }
50     for1(i,t){
51         int l=1,r=0;
52         for1(j,b){
53             while(q[r].w>=a[i][j]&&l<=r&&r)r--;
54             while(q[l].id<j-n+1&&l<=r&&l)l++;
55             q[++r].id=j;q[r].w=a[i][j];
56             g[i][j]=q[l].w;
57         }
58     }
59     int ans=inf;
60     for(int i=1;i<=t-n+1;i++)
61         for(int j=n;j<=b;j++){
62             int mi=inf,mx=0;
63             for0(k,n-1){
64                 mi=min(mi,g[i+k][j]);
65                 mx=max(mx,f[i+k][j]);
66             }
67             ans=min(ans,mx-mi);
68         }
69     printf("%d",ans);
70     return 0;
71 }
View Code

 

posted @ 2016-05-19 11:00  HTWX  阅读(107)  评论(0编辑  收藏  举报