bzoj 1127 贪心+悬线法
来源:互联网 发布:634741网络语什么意思 编辑:程序博客网 时间:2024/06/06 06:47
题意:给定一个n*n的矩阵,求一个子矩阵满足权值和属于[k,2*k] (special judge )
思路棒极了(┙>∧<)┙へ┻┻
对一个一维的[l,r],如果这个区间满足 任取x, x<k 且 区间和>=k ,那么答案肯定存在在这个区间中
证明:
因为这个区间里,任意x均满足x<k,所以每加上一个数,区间和的变化量属于[0.k)
所以不会存在一个数,使得一个连续的子区间的区间和加上它以后直接从小于k越过[k,2*k]的区间,瞬间达到大于k
所以只要找到这个[l,r],并从这个区间的左端或右端开始一一删除判断,就可以得到答案的区间
虽然这是一维下的结论,但是这个结论是可以拓展的ヽ(•̀ω•́ )ゝ
即:一个子矩阵满足 任取x,x<k 且 区间和>=k,那么答案肯定存在在这个子矩阵里
所以只要找到这个子矩阵,就可以类比上面的方法删一删就能得到答案的区间,具体:
(1)如果是一行的话,退化成了一维问题,只要从左端或右端开始一一删除判断即可
(2)如果是个子矩阵的话,从最上一行或最下一行一行一行的删除,直到删得还剩一行,按上面的继续处理
然后就是要O(n^2)的找到子矩阵,把大于2*k的点看做障碍点,用悬线法,得到最大子矩阵,一一判断即可
当然,如果一开始读入的时候,如果一个1*1的位置就已经满足[k,2*k],直接输出即可~(~o ̄▽ ̄)~o。。。
var n,m :longint; flag :boolean; sum,map :array[0..2010,0..2010] of int64; l,r,h :array[0..2010,0..2010] of longint; i,j :longint;function min(a,b:longint):longint;begin if a<b then exit(a) else exit(b);end;function get_sum(x1,y1,x2,y2:longint):int64;begin exit(sum[x2,y2]-sum[x1-1,y2]-sum[x2,y1-1]+sum[x1-1,y1-1]);end;function check:boolean;var i,j:longint;begin for i:=1 to n do for j:=1 to n do if (map[i,j]>=m) and (map[i,j]<=2*m) then begin writeln(j,' ',i,' ',j,' ',i); exit(true); end; exit(False);end;procedure cut(x1,y1,x2,y2:longint);var i,j:longint;begin while get_sum(x1,y1,x2,y2)>2*m do begin if x1=x2 then dec(y2) else if get_sum(x1+1,y1,x2,y2)>=m then inc(x1) else dec(x2); end; flag:=true; writeln(y1,' ',x1,' ',y2,' ',x2);end;begin read(m,n); for i:=1 to n do for j:=1 to n do read(map[i,j]); if not check then begin for i:=1 to n do for j:=1 to n do sum[i,j]:=map[i,j]+sum[i,j-1]+sum[i-1,j]-sum[i-1,j-1]; for i:=1 to n do begin for j:=1 to n do if (map[i,j]>2*m) then l[i,j]:=0 else l[i,j]:=l[i,j-1]+1; for j:=n downto 1 do if (map[i,j]>2*m) then r[i,j]:=0 else r[i,j]:=r[i,j+1]+1; end; // for i:=2 to n do for j:=1 to n do if (map[i,j]<=2*m) and (map[i-1,j]<=2*m) then begin h[i,j]:=h[i-1,j]+1; l[i,j]:=min(l[i,j],l[i-1,j]); r[i,j]:=min(r[i,j],r[i-1,j]); end; // for i:=1 to n do for j:=1 to n do if (map[i,j]<=2*m) then if (get_sum(i-h[i,j],j-l[i,j]+1,i,j+r[i,j]-1)>=m) then begin cut(i-h[i,j],j-l[i,j]+1,i,j+r[i,j]-1);break; end; if not flag then writeln('NIE'); end;end.——by Eirlys
0 0
- bzoj 1127 贪心+悬线法
- 【贪心】【bzoj 3008】: 象棋
- bzoj 1696 贪心
- BZOJ 3721 贪心
- bzoj 1034 泡泡堂|贪心
- 【贪心】 BZOJ 3252:攻略
- BZOJ 4027 贪心
- [贪心] BZOJ 2697 特技飞行
- BZOJ 1193 搜索+贪心
- BZOJ 2151 种树 贪心
- BZOJ 4582 贪心
- bzoj 1572 贪心
- BZOJ 1577 贪心
- bzoj 2697: 特技飞行 贪心
- bzoj 1029 贪心+堆
- BZOJ 3143 高斯消元+贪心....
- bzoj 2802 贪心+堆
- bzoj 1572 贪心+堆
- 蓝牙(BluetoothAdapterj & BluetoothDevice)实例解析
- hdu 1078 FatMouse and Cheese
- SpringBoot Logback日志配置
- Linux 字符设备驱动实例笔记
- RatingBar自定义图片大小如何确定
- bzoj 1127 贪心+悬线法
- Java内存分配管理知识点
- Microsoft Visio 2013在安装过程中出错的一种解决方案
- HexString与BinaryString间转换
- Java学习之序列化
- 随处办公时代,轻薄是笔记本的重要方向之一
- 声纹识别服务云平台的意义以及趋势(感想)
- Spring Boot Web Error Page处理
- 树