bzoj 1047 单调队列
来源:互联网 发布:零基础学java第4版pdf 编辑:程序博客网 时间:2024/05/17 22:18
题意:在a*b的矩阵里,找到一个n*n的子矩阵,使这个子矩阵里的最大值与最小值的差最小
n是固定的,484很像一个固定的窗口在一个面上移动
如果把题目的条件改为一维,
即给定一个序列,窗口长度是n,求这个窗口里最大值与最小值,你会想起什么?
对,没错,就是单调队列
但这是二维怎么破?
拆成一维呀
先对每一行i以它在矩阵里的值为基础,维护两个单调队列f1、g1,分别维护[i,j-n+1]到[i,j]这个窗口的最大值和最小值
再对每一列j以刚才得到的f1、g1为基础,再分别维护两个单调队列f2、g2,分别维护[i-n+1,j]到[i,j]这个窗口的最大值和最小值
这样,最后得到的f2[i,j]、g2[i,j]实际上就是以[i,j]为右下角的n*n的窗口的最大值和最小值
ans=min{f2[i,j]-g2[i,j]} (n<=i<=a,n<=j<=b);
uses math;var a,b,n,ans :longint; i,j :longint; map,f,g,f2,g2 :array[0..1510,0..1510] of longint; que :array[0..1510] of longint;procedure work1(x:longint);var j,h,tl:longint;begin h:=1; tl:=1; que[1]:=1; f[x,1]:=map[x,1]; for j:=2 to b+5 do que[j]:=0; for j:=2 to b do begin while (h<=tl) and (j-que[h]>=n) do inc(h); f[x,j]:=max(map[x,j],map[x,que[h]]); while (h<=tl) and (map[x,que[tl]]<=map[x,j]) do dec(tl); inc(tl); que[tl]:=j; end;end;procedure work2(x:longint);var j,h,tl:longint;begin h:=1; tl:=1; que[1]:=1; g[x,1]:=map[x,1]; for j:=2 to b+5 do que[j]:=0; for j:=2 to b do begin while (h<=tl) and (j-que[h]>=n) do inc(h); g[x,j]:=min(map[x,j],map[x,que[h]]); while (h<=tl) and (map[x,que[tl]]>=map[x,j]) do dec(tl); inc(tl); que[tl]:=j; end;end;procedure work3(y:longint);var i,h,tl:longint;begin h:=1; tl:=1; que[1]:=1; f2[1,y]:=f[1,y]; for i:=2 to a+5 do que[i]:=0; for i:=2 to a do begin while (h<=tl) and (i-que[h]>=n) do inc(h); f2[i,y]:=max(f[que[h],y],f[i,y]); while (h<=tl) and (f[que[tl],y]<=f[i,y]) do dec(tl); inc(tl); que[tl]:=i; end;end;procedure work4(y:longint);var i,h,tl:longint;begin h:=1; tl:=1; que[1]:=1; g2[1,y]:=g[1,y]; for i:=2 to a+5 do que[i]:=0; for i:=2 to a do begin while (h<=tl) and (i-que[h]>=n) do inc(h); g2[i,y]:=min(g[que[h],y],g[i,y]); while (h<=tl) and (g[que[tl],y]>=g[i,y]) do dec(tl); inc(tl); que[tl]:=i; end;end;begin //assign(input,'square.in');reset(input); //assign(output,'square.out');rewrite(output); read(a,b,n); for i:=1 to a do for j:=1 to b do read(map[i,j]); // for i:=1 to a do begin work1(i); work2(i); end; // for i:=1 to b do begin work3(i); work4(i); end; // ans:=maxlongint; for i:=n to a do for j:=n to b do ans:=min(ans,f2[i,j]-g2[i,j]); writeln(ans); //close(input); close(output);end.
——by Eirlys
0 0
- BZOJ 1047 单调队列
- bzoj 1047 单调队列
- bzoj 1047(单调队列)
- BZOJ 4385 单调队列
- BZOJ 2096 单调队列
- bzoj 2227 单调队列
- BZOJ 1342 单调队列
- BZOJ 1012 单调队列+二分
- BZOJ 2096: pilots 单调队列
- BZOJ 1047 HAOI2007 理想的正方形 单调队列
- BZOJ 1047 HAOI 2007 理想的正方形 单调队列
- [BZOJ 1047] HAOI 2007 理想的正方形 · 单调队列
- bzoj 1047 [HAOI2007]理想的正方形 单调队列
- bzoj 1047: [HAOI2007]理想的正方形 (单调队列)
- BZOJ 1047 [HAOI2007]理想的正方形【单调队列
- BZOJ 1047 单调队列求二维滑动窗口最值
- BZOJ 1047: [HAOI2007]理想的正方形(单调队列)
- 【单调队列】BZOJ 1047 [HAOI2007]理想的正方形
- 数据库<4>
- python3的urllib的request模块
- MySQL --DML语句
- DML语句---插入单条数据记录
- 面向对象
- bzoj 1047 单调队列
- MySQL/ 字段
- 数据库
- Mac版本android studio快捷键
- 安装jar到本地maven仓库
- 数据库
- java良好的编码习惯
- 继承
- 命令行操作数据库