bzoj1047/haoi2007 理想的正方形
作者:互联网
题目描述
有一个ab的整数组成的矩阵,现请你从中找出一个nn的正方形区域,使得该区域所有数中的最大值和最小值的差最小。
输入格式
第一行为3个整数,分别表示a,b,n的值
第二行至第a+1行每行为b个非负整数,表示矩阵中相应位置上的数。每行相邻两数之间用一空格分隔。
输出格式
仅一个整数,为ab矩阵中所有“nn正方形区域中的最大整数和最小整数的差值”的最小值。
输入输出样例
输入 #1
5 4 2
1 2 5 6
0 17 16 0
16 17 2 1
2 10 2 1
1 2 2 2
输出 #1
1
说明/提示
问题规模
(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
分析
这题简直就是为了单调队列而单调队列(当然可以用st表)
代码
#include <bits/stdc++.h>
#define N 1005
#define inf 2147483647
using namespace std;
int mp[N][N], f[N][N], g[N][N], q[N], x, y, p[N], a, b, ans = inf;
int main(){
int i, j, n, m, k;
scanf("%d%d%d", &n, &m, &k);
for(i = 1; i <= n; i++)
for(j = 1; j <= m; j++) scanf("%d", &mp[i][j]);
for(i = 1; i <= n; i++){
x = 1, y = 0;
for(j = 1; j <= m; j++){
q[++y] = j;
if(x < y && (j - q[x] + 1) > k) x++;
while(x < y && mp[i][q[y]] > mp[i][q[y-1]]) q[y-1] = q[y], y--;
if(j >= k) f[i][j - k + 1] = mp[i][q[x]];
}
}
for(i = 1; i <= n; i++){
x = 1, y = 0;
for(j = 1; j <= m; j++){
q[++y] = j;
if(x < y && (j - q[x] + 1) > k) x++;
while(x < y && mp[i][q[y]] < mp[i][q[y-1]]) q[y-1] = q[y], y--;
if(j >= k) g[i][j - k + 1] = mp[i][q[x]];
}
}
//for(i = 1; i <= n; i++) printf("%d\n", f[i][1]);
for(j = 1; j <= m - k + 1; j++){
a = 1, b = 0;
x = 1, y = 0;
for(i = 1; i <= n; i++){
q[++y] = i;
p[++b] = i;
if(x < y && (i - q[x] + 1) > k) x++;
if(a < b && (i - p[a] + 1) > k) a++;
while(x < y && f[q[y]][j] > f[q[y-1]][j]) q[y-1] = q[y], y--;
while(a < b && g[p[b]][j] < g[p[b-1]][j]) p[b-1] = p[b], b--;
if(i >= k){
ans = min(ans, f[q[x]][j] - g[p[a]][j]);
}
}
}
printf("%d", ans);
return 0;
}
标签:++,整数,haoi2007,正方形,while,bzoj1047,mp,&&,ans 来源: https://blog.csdn.net/iamhpp/article/details/99695885