码迷,mamicode.com
首页 > 其他好文 > 详细

HihoCoder1673 : 01间隔矩阵([Offer收割]编程练习赛41)(单调队列)

时间:2017-12-24 21:22:52      阅读:212      评论:0      收藏:0      [点我收藏+]

标签:整数   pos   并且   amp   stream   color   编程练习   hihocoder   size   

 

描述

给定一个N × M的01矩阵,小Hi希望从中找到一个01间隔的子矩阵,并且子矩阵的面积越大越好。

例如对于

0101010

1000101

0101010

1010101

0101010

在右侧有一个5 × 4的01间隔子矩阵,在下方有一个3 × 7的01间隔子矩阵。

输入

第一行包含两个整数N和M。  

以下N行M列包含一个N × M的01矩阵。  

对于30%的数据,1 ≤ N, M ≤ 250  

对于100%的数据,1 ≤ N, M ≤ 2000

输出

输出最大的01间隔子矩阵的面积。

样例输入

5 7  
0101010
1000101
0101010
1010101
0101010

样例输出

21
  • 模型:滑动窗口,最大广告牌面积
  • 手段:单调队列
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<cstring>
#include<cmath>
using namespace std;
const int maxn=2010;
char c[maxn][maxn];
int H[maxn][maxn],L[maxn][maxn],R[maxn][maxn],n,m,i,j,ans=0;;
int main()
{
    scanf("%d%d",&n,&m);
    for(i=1;i<=n;i++) scanf("%s",c[i]+1);
    
    for(i=1;i<=m;i++) H[1][i]=1;                 //得到h 
    for(i=1;i<=m;i++)
      for(j=2;j<=n;j++)
        H[j][i]=c[j][i]==c[j-1][i]?1:H[j-1][i]+1;
    
    for(i=1;i<=n;i++)                            //得到相应h的左延伸 
     for(j=1;j<=m;j++){
         if(j==1) { L[i][j]=1;continue;}//边界处理 
         int k=j;
         while(k>1&&c[i][k]!=c[i][k-1]&&H[i][k-1]>=H[i][j]) k=L[i][k-1]; 
         L[i][j]=k;
     }
     
    for(i=1;i<=n;i++)                             //得到相应h的右延伸 
     for(j=m;j>=1;j--){
         if(j==m) {R[i][j]=m;continue;}
         int k=j;
         while(k&&k<m&&c[i][k]!=c[i][k+1]&&H[i][k+1]>=H[i][j]) k=R[i][k+1]; 
         R[i][j]=k;
     } 
     
    for(i=1;i<=n;i++) 
     for(j=1;j<=m;j++)
        if((R[i][j]-L[i][j]+1)*H[i][j]>ans)  ans=(R[i][j]-L[i][j]+1)*H[i][j];
    
    printf("%d\n",ans);
    return 0;
}

 

HihoCoder1673 : 01间隔矩阵([Offer收割]编程练习赛41)(单调队列)

标签:整数   pos   并且   amp   stream   color   编程练习   hihocoder   size   

原文地址:http://www.cnblogs.com/hua-dong/p/8098932.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!