bzoj1047

单调队列好东西。。。。

先跑第一遍处理出每行以(x,y)结尾长度为n的一段的max与min

再跑一遍处理出每列以(x,y)结尾长度为n的一段的max的max以及min的min

 1 #include<bits/stdc++.h>
 2 #define lowbit(a) ((a)&(-(a)))
 3 #define clr(a,x) memset(a,x,sizeof(a))
 4 #define rep(i,l,r) for(int i=l;i<(r);i++)
 5 typedef long long ll;
 6 using namespace std;
 7 int read()
 8 {
 9     char c=getchar();
10     int ans=0,f=1;
11     while(!isdigit(c)){
12         if(c=='-') f=-1;
13         c=getchar();
14     }
15     while(isdigit(c)){
16         ans=ans*10+c-'0';
17         c=getchar();
18     }
19     return ans*f;
20 }
21 const int maxa=1009,maxb=1009,inf=0x7fffffff;
22 int a,b,n,A[maxa][maxb],mn[maxa][maxb],mx[maxa][maxb];
23 int main()
24 {    
25     a=read(),b=read(),n=read();
26     rep(i,0,a){
27         rep(j,0,b) A[i][j]=read();
28     }
29     rep(i,0,a){
30         deque<int>Qmax,Qmin;
31         rep(j,0,b){
32             while(!Qmax.empty()&&Qmax.front()<j-n+1) Qmax.pop_front();
33             while(!Qmin.empty()&&Qmin.front()<j-n+1) Qmin.pop_front();
34             while(!Qmax.empty()&&A[i][Qmax.back()]<=A[i][j]) Qmax.pop_back();
35             while(!Qmin.empty()&&A[i][Qmin.back()]>=A[i][j]) Qmin.pop_back();
36             Qmax.push_back(j);Qmin.push_back(j);
37             if(j>=n-1) mx[i][j]=A[i][Qmax.front()],mn[i][j]=A[i][Qmin.front()];
38         }
39     }
40     int ans=inf;
41     rep(i,n-1,b){
42         deque<int>Qmax,Qmin;
43         rep(j,0,a){
44             while(!Qmax.empty()&&Qmax.front()<j-n+1) Qmax.pop_front();
45             while(!Qmin.empty()&&Qmin.front()<j-n+1) Qmin.pop_front();
46             while(!Qmax.empty()&&mx[Qmax.back()][i]<=mx[j][i]) Qmax.pop_back();
47             while(!Qmin.empty()&&mn[Qmin.back()][i]>=mn[j][i]) Qmin.pop_back();
48             Qmax.push_back(j);Qmin.push_back(j);
49             if(j>=n-1) ans=min(ans,mx[Qmax.front()][i]-mn[Qmin.front()][i]);
50         }
51     }
52     printf("%d\n",ans);
53     return 0;
54 }
View Code

1047: [HAOI2007]理想的正方形

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 2062  Solved: 1095
[Submit][Status][Discuss]

Description

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

Input

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

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

HINT

 

问题规模

(1)矩阵中的所有数都不超过1,000,000,000

(2)20%的数据2<=a,b<=100,n<=a,n<=b,n<=10

(3)100%的数据2<=a,b<=1000,n<=a,n<=b,n<=100

 

Source

 
[Submit][Status][Discuss]
posted @ 2015-08-19 15:57  ChenThree  阅读(177)  评论(0编辑  收藏  举报