首页 > 代码库 > HAOI2007 理想的正方形
HAOI2007 理想的正方形
1047: [HAOI2007]理想的正方形
Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1402 Solved: 738
[Submit][Status]
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
1 2 5 6
0 17 16 0
16 17 2 1
2 10 2 1
1 2 2 2
Sample Output
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
问题规模
(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
HINT
题解:
真是一道好题!
我一开始只想到了二维的RMQ,分析了一下时间和空间复杂度,感觉都承受不起……
一看题解,恍然大悟,因为该问题的特殊性,固定了以n为边长,所以只要用单调队列即可,RMQ多余了,用不到RMQ的优点
(而且,我参看的大牛的代码很巧妙的使代码量降了下来,如下这是一种技巧,以后要掌握)
代码:
1 uses math; 2 var f:array[1..2,0..1100,0..1100] of longint; 3 g,c:array[0..1100,0..1100] of longint; 4 i,j,a,b,n,ans:longint; 5 procedure init; 6 begin 7 readln(a,b,n); 8 for i:=1 to a do 9 begin10 for j:=1 to b do read(c[i,j]);11 readln;12 end;13 end;14 procedure work(x:longint);15 var i,j,l,r:longint;16 q:array[0..1500] of longint;17 begin18 for i:=1 to a do19 begin20 fillchar(q,sizeof(q),0);21 l:=1;r:=0;22 for j:=1 to b do23 begin24 while (l<=r) and (c[i,q[r]]<=c[i,j]) do dec(r);25 inc(r);q[r]:=j;26 while (l<r) and (q[l]<j-n+1) do inc(l);27 g[i,j]:=c[i,q[l]];28 end;29 end;30 for i:=1 to b do31 begin32 fillchar(q,sizeof(q),0);33 l:=1;r:=0;34 for j:=1 to a do35 begin36 while (l<=r) and (g[q[r],i]<=g[j,i]) do dec(r);37 inc(r);q[r]:=j;38 while (l<r) and (q[l]<j-n+1) do inc(l);39 f[x,j,i]:=g[q[l],i];40 end;41 end;42 end;43 procedure main;44 begin45 work(1);46 for i:=1 to a do47 for j:=1 to b do48 c[i,j]:=0-c[i,j];49 work(2);50 ans:=maxlongint;51 for i:=n to a do52 for j:=n to b do53 ans:=min(ans,f[1,i,j]+f[2,i,j]);54 writeln(ans);55 end;56 begin57 init;58 main;59 end.
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。