codevs 最大全0子矩阵
来源:互联网 发布:一年级孩子认字软件 编辑:程序博客网 时间:2024/06/05 01:12
这个题可以预处理矩阵前缀和然后用n^3的方法解决,可是明显会超时,所以有一种n^2的算法。
我们可以一行一行的去算,设h[j]为从当前行开始向上数连续的0的个数(当前第i行也为0),如果当前位置等于1的话那么h[j]=0。
比如说样例:
5
0 1 0 1 0
0 0 0 0 0
0 0 0 0 1
1 0 0 0 0
0 1 0 0 0
那么每个位置的h[j]为
1 0 1 0 1
2 1 2 1 2
3 2 2 2 0
0 3 4 3 1
1 0 5 4 2
然后我们在求出来每一行h[j]的同时,去找当前位置可以到达的左边界和右边界。我们设l[j],r[j]为左右边界。我们设l[j],r[j]初始值都为j。显然,如果h[j]<=h[l[j]-1],那么l[j]=l[l[j]-1];对应着,如果h[j]<=h[r[j]+1],那么r[j]=r[r[j]+1];
我们来举个例子;
还有一个要注意的问题,因为到每一行的时候,h[j]都会跟着更新,所以我们每次求出来h[j]的时候应该紧跟着去求他的l和r,并且算面积。
#include<cstdio> #include<iostream>#include<algorithm>using namespace std;int h[2100],map[2100][2100],l[2100],r[2100];int main(){ int n; cin>>n; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++){ cin>>map[i][j]; } int ans=0; for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){//一行一行处理,h[j]存储的是到第i行时,在第j列从i行开始往上的0的个数 if(map[i][j]==0)h[j]++; else h[j]=0; } for(int j=1;j<=n;j++){//每一行都要去算 l[j]=j; while(l[j]>1&&h[j]<=h[l[j]-1])l[j]=l[l[j]-1];//如果能够扩展就向左扩展 } for(int j=n;j>=1;j--){//注意这里要从右向左,因为我们是根据右边的更新左边的 r[j]=j; while(r[j]<n&&h[j]<=h[r[j]+1])r[j]=r[r[j]+1]; } for(int j=1;j<=n;j++) ans=max(h[j]*(r[j]-l[j]+1),ans); } cout<<ans<<endl;}
0 0
- codevs 1159 最大全0子矩阵
- Codevs 1159最大全0子矩阵
- codevs 1159 最大全0子矩阵
- codevs 最大全0子矩阵
- 【codevs 1159】最大全0子矩阵
- codevs天梯 最大全0子矩阵
- 【codevs 1159】最大全0子矩阵 (悬线法)
- codevs 1159 最大全0子矩阵 悬线法
- Codevs 1159 最大全0子矩阵 悬线法!!!!
- 求最大子矩阵悬线法(codevs 1159 最大全0子矩阵)
- <单调栈/悬线法>codevs 2491 玉蟾宫 1159 最大全0子矩阵
- cv1159 最大全0子矩阵(极大子矩阵)
- [codevs1159]最大全0子矩阵(极大子矩阵)
- wiki 1159 最大全0子矩阵
- 【dp】最大全0子矩阵
- [codevs1159]最大全0子矩阵
- code vs 最大全0子矩阵
- 【codevs1159】最大全0子矩阵
- python中join()和split()的用法
- 不懂职场杠杆,35岁后你就会这样被“干”掉
- 禁止截屏
- 【玲珑杯】1048 - Best substring【manacher+分治维护凸壳】
- 计算机视觉、机器学习相关领域论文和源代码大集合
- codevs 最大全0子矩阵
- Eclipse控制台输出信息的控制
- 设置 Eclipse 中的 Tab 键为 4 个空格
- java 加密技术AES、MD5、RSA
- android 标题栏 状态栏的隐藏
- Android 避免内存泄漏
- 开源python网络爬虫框架Scrapy
- MOS器件公示总结
- 浅析Java虚拟机结构与机制