1047: [HAOI2007]理想的正方形
Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 3311 Solved: 1819
[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
1 2 5 6
0 17 16 0
16 17 2 1
2 10 2 1
1 2 2 2
Sample Output
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> const int inf = 1000000000; using namespace std; int a, b, n, map[1010][1010], q1[1010], q2[1010], num1[1010], num2[1010], maxx[1010][1010], minx[1010][1010], ans = inf; void solve1() { int l1, r1, l2, r2; for (int j = 1; j <= b; j++) { l1 = l2 = 1; r1 = r2 = 0; for (int i = 1; i <= a; i++) { //队列1 while (l1 <= r1 && i - num1[l1] >= n) l1++; while (l1 <= r1 && q1[r1] < map[i][j]) r1--; q1[++r1] = map[i][j]; num1[r1] = i; //队列2 while (l2 <= r2 && i - num2[l2] >= n) l2++; while (l2 <= r2 && q2[r2] > map[i][j]) r2--; q2[++r2] = map[i][j]; num2[r2] = i; if (i >= n) { maxx[i][j] = q1[l1]; minx[i][j] = q2[l2]; } } } } void solve2() { int l1, r1, l2, r2; for (int i = 1; i <= a; i++) { l1 = l2 = 1; r1 = r2 = 0; for (int j = 1; j <= b; j++) { while (l1 <= r1 && j - num1[l1] >= n) l1++; while (l1 <= r1 && q1[r1] < maxx[i][j]) r1--; q1[++r1] = maxx[i][j]; num1[r1] = j; while (l2 <= r2 && j - num2[l2] >= n) l2++; while (l2 <= r2 && q2[r2] > minx[i][j]) r2--; q2[++r2] = minx[i][j]; num2[r2] = j; if (i >= n && j >= n) ans = min(ans, q1[l1] - q2[l2]); } } } int main() { scanf("%d%d%d", &a, &b, &n); for (int i = 1; i <= a;i++) for (int j = 1; j <= b; j++) scanf("%d", &map[i][j]); solve1(); solve2(); printf("%d", ans); return 0; }