[BZOJ1047][HAOI2007]理想的正方形

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 }
View Code

 

posted @ 2017-09-20 18:28  wls001  阅读(124)  评论(0编辑  收藏  举报