BZOJ 1047: [HAOI2007]理想的正方形( 单调队列 )

单调队列..先对每一行扫一次维护以每个点(x, y)为结尾的长度为n的最大最小值.然后再对每一列扫一次, 在之前的基础上维护(x, y)为结尾的长度为n的最大最小值. 时间复杂度O(ab)

(话说还是deque2048ms快..list3572ms慢死了)

#include<bits/stdc++.h>

using namespace std;

const int maxn = 1009;

int X[maxn][maxn], R, C, N;
int MN[maxn][maxn], MX[maxn][maxn];
deque<int> MIN, MAX;

int main() {
	
	cin >> R >> C >> N;
	for(int i = 0; i < R; i++)
	    for(int j = 0; j < C; j++)
	        scanf("%d", &X[i][j]);
	
	for(int i = 0; i < R; i++) {
		MIN.clear(); MAX.clear();
		for(int j = 0; j < C; j++) {
			while(!MIN.empty() && MIN.front() + N <= j) MIN.pop_front();
			while(!MAX.empty() && MAX.front() + N <= j) MAX.pop_front();
		    while(!MIN.empty() && X[i][MIN.back()] >= X[i][j]) MIN.pop_back();
		    while(!MAX.empty() && X[i][MAX.back()] <= X[i][j]) MAX.pop_back();
		    MIN.push_back(j);
			MAX.push_back(j);
			if(j + 1 >= N) {
				MN[i][j - N + 1] = X[i][MIN.front()];
				MX[i][j - N + 1] = X[i][MAX.front()];
			}
		}
	}
	
	int ans = 2000000000;
	for(int j = 0; j + N <= C; j++) {
		MIN.clear(); MAX.clear();
		for(int i = 0; i < R; i++) {
			while(!MIN.empty() && MIN.front() + N <= i) MIN.pop_front();
			while(!MAX.empty() && MAX.front() + N <= i) MAX.pop_front();
			while(!MIN.empty() && MN[MIN.back()][j] >= MN[i][j]) MIN.pop_back();
			while(!MAX.empty() && MX[MAX.back()][j] <= MX[i][j]) MAX.pop_back();
			MIN.push_back(i);
			MAX.push_back(i);
			if(i + 1 >= N)
			    ans = min(ans, MX[MAX.front()][j] - MN[MIN.front()][j]);
		}
	}
	printf("%d\n", ans);
	
	return 0;
}

  

1047: [HAOI2007]理想的正方形

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 2058  Solved: 1093
[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

posted @ 2015-08-14 21:45  JSZX11556  阅读(280)  评论(0编辑  收藏  举报