bzoj1047: [HAOI2007]理想的正方形

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 2 5 6
0 17 16 0
16 17 2 1
2 10 2 1
1 2 2 2

Sample Output

1

两层单调队列
连i,j都打错居然过了三个点。。。QwQ
 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 using namespace std;
 5 
 6 inline int read(){
 7     char ch;
 8     int re=0;
 9     bool flag=0;
10     while((ch=getchar())!='-'&&(ch<'0'||ch>'9'));
11     ch=='-'?flag=1:re=ch-'0';
12     while((ch=getchar())>='0'&&ch<='9')  re=re*10+ch-'0';
13     return flag?-re:re;
14 }
15 
16 const int maxn=1001;
17 
18 int n,m,d,l,r,ans=0x3f3f3f3f;
19 int a[maxn][maxn],site[maxn],val[maxn];
20 int min_site[maxn][maxn],max_site[maxn][maxn],t1[maxn],t2[maxn];
21 
22 void init(){
23     n=read();  m=read();  d=read();
24     for(int i=1;i<=n;i++)
25         for(int j=1;j<=m;j++)
26             a[i][j]=read();
27 }
28 
29 void solve(){
30     for(int i=1;i<=n;i++){
31         l=1;  r=1;
32         for(int j=1;j<=m;j++){
33             while(l<r&&val[r-1]<=a[i][j])  r--;
34             val[r]=a[i][j];  site[r]=j;  r++;
35             if(site[l]==j-d)  l++;
36             if(j>=d)  max_site[i][j]=val[l];
37         }
38         l=1;  r=1;
39         for(int j=1;j<=m;j++){
40             while(l<r&&val[r-1]>=a[i][j])  r--;
41             val[r]=a[i][j];  site[r]=j;  r++;
42             if(site[l]==j-d)  l++;
43             if(j>=d)  min_site[i][j]=val[l];
44         }
45     }
46     for(int i=d;i<=m;i++){
47         l=1;  r=1;
48         for(int j=1;j<=n;j++){
49             while(l<r&&val[r-1]>=min_site[j][i])  r--;
50             val[r]=min_site[j][i];  site[r]=j;  r++;
51             if(site[l]==j-d)  l++;
52             if(j>=d)  t1[j]=val[l];
53         }
54         l=1;  r=1;
55         for(int j=1;j<=n;j++){
56             while(l<r&&val[r-1]<=max_site[j][i])  r--;
57             val[r]=max_site[j][i];  site[r]=j;  r++;
58             if(site[l]==j-d)  l++;
59             if(j>=d)  t2[j]=val[l];
60         }
61         for(int j=d;j<=n;j++)  ans=min(ans,t2[j]-t1[j]);
62     }
63     printf("%d\n",ans);
64 }
65 
66 int main(){
67     //freopen("temp.in","r",stdin);
68     init();
69     solve();
70     return 0;
71 }

 

posted @ 2017-07-09 18:54  ZYBGMZL  阅读(139)  评论(0编辑  收藏  举报