Codeforces 22B Bargaining Table【暴力+思维】

来源:互联网 发布:自学程序员好找工作吗 编辑:程序博客网 时间:2024/05/29 19:09

B. Bargaining Table
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

Bob wants to put a new bargaining table in his office. To do so he measured the office room thoroughly and drew its plan: Bob's office room is a rectangular roomn × m meters. Each square meter of the room is either occupied by some furniture, or free. A bargaining table is rectangular, and should be placed so, that its sides are parallel to the office walls. Bob doesn't want to change or rearrange anything, that's why all the squares that will be occupied by the table should be initially free. Bob wants the new table to sit as many people as possible, thus its perimeter should be maximal. Help Bob find out the maximum possible perimeter of a bargaining table for his office.

Input

The first line contains 2 space-separated numbers n andm (1 ≤ n, m ≤ 25) — the office room dimensions. Then there follown lines with m characters 0 or 1 each. 0 stands for a free square meter of the office room. 1 stands for an occupied square meter. It's guaranteed that at least one square meter in the room is free.

Output

Output one number — the maximum possible perimeter of a bargaining table for Bob's office room.

Examples
Input
3 3000010000
Output
8
Input
5 411000000000000000000
Output
16

题目大意:

给你一个N*M的矩阵,1表示已经占用了,0表示没有被占用,求一个由0构成的矩阵,使其周长最大。


思路:


1、我们从第一行开始暴力处理,处理出这一行中,每一个格子向下延展都能延展出几个0,记做h【i】;

例如样例1中第一行:

h【0】=3,h【1】=1,h【2】=3;

得到这样一个图:


那么此时相当于在这样的一个图上,找一个最大矩阵,使其周长最大。

那么我们对每一行都这样处理一遍,都找到了其当前情况的最大矩阵,那么对应维护一个最大值即可。


2、那么我们要如何在这样一个图上找到最大子矩阵呢?

①我们设定l【i】表示比h【i】连续大的最左边的位子,r【i】表示比r【i】连续大的最右边的位子。

②那么我们对应枚举以h【i】组成的最大子矩阵的纵向长度就是h【i】,横向长度就是r【i】-l【i】+1

③那么其当前以h【i】为纵向长度的子矩阵的周长为:2*(r【i】-l【i】+1)+2*h【i】;

④维护一个最大周长输出即可。


3、注意当h【i】==0的时候 ,我们就不要处理了。


Ac代码:

#include<stdio.h>#include<string.h>#include<iostream>using namespace std;int n,m;char a[35][35];int h[35];int l[35];int r[35];int output;void Slove(){    for(int i=0;i<m;i++)    {        if(h[i]==0)continue;        for(int j=i;j>=0;j--)        {            if(h[j]>=h[i])l[i]=j;            else break;        }        for(int j=i;j<m;j++)        {            if(h[j]>=h[i])r[i]=j;            else break;        }    }    for(int i=0;i<m;i++)    {        output=max(output,h[i]*2+(r[i]-l[i]+1)*2);    }}int main(){    while(~scanf("%d%d",&n,&m))    {        for(int i=0;i<n;i++)        {            scanf("%s",a[i]);        }        output=0;        for(int i=0;i<n;i++)        {            for(int j=0;j<m;j++)            {                int cont=0;                int y=i;                while(1)                {                    if(a[y][j]=='0')                    {                        cont++;                        y++;                        if(y==n)break;                    }                    else break;                }                h[j]=cont;            }            Slove();        }        printf("%d\n",output);    }}





0 0