51nod1787 largest square sub-matrix

51nod1787 largest square sub-matrix

I cut the top of the first questions in 51nod

I cut in 51nod above the first channel 8 title

I cut in a blood over the first channel 8 51nod question

Subject to the effect

A n * m matrix, each matrix element is 'X' or '', there are several modification operation, each time a modification operation is a '' into 'X', after the modification required calculate the current matrix which contains only '' is how much of the maximum square sub-matrix, the output matrix to the side length.

Entry

A single set of test data.
The first line contains three integers n, m and k (1 <= n, m , k <= 2000), the size and number represent the modified matrix.
Next n lines, each line there are m characters 'X' or '.'.
Next k rows, each row has two integers xi, yi (1≤xi≤n, 1≤yi≤m) , represented by the point marked modified.
To ensure that the input coordinates must be above character '.'.

Export

Output k rows, each corresponding to the maximum after the sub-modified matrix side length.

answer

First, do upside down, add the 'X' changed to delete 'X'.

The initial answer may find the answer to half

If you deleted (x, y) at the 'X' answer becomes large, then the answer is clear that the matrix comprises a (x, y)

So let's think contains (x, y) is the maximum legal sub-matrix.

Maintenance mal [x] [y], mar [x] [y] represented by (x, y) can be extended to the left to the right of the longest distance.

Then it is assumed the boundaries of the new matrix is ​​the answer l, the lower boundary of r, to ensure lateral width is always greater than or equal vertical lengths (i.e., r-l + 1)

l to r sure of the time down to the monotonous down.

Therefore, the complexity is O ( \ (^ n-2 \) ) of

Code

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

int n,m,k,i,l,r,mid,x,y;
char map[2005][2005];
int sum[2005][2005];
int mal[2005][2005],mar[2005][2005];
int exl[2005],exr[2005];
int q[2005][2];
int ans[2005];

void preprocess()
{
    int i,j;
    for (i=1;i<=n;i++)
    {
        for (j=1;j<=m;j++)
        {
            sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1];
            if (map[i][j]=='X')
            sum[i][j]++;
        }
    }
}

int pd(int len)
{
    int i,j;
    for (i=1;i<=n;i++)
    {
        for (j=1;j<=m;j++)
        {
            if ((i+len-1>n)||(j+len-1>m)) continue;
            if (sum[i+len-1][j+len-1]-sum[i-1][j+len-1]-sum[i+len-1][j-1]+sum[i-1][j-1]==0) return 1;
        }
    }
    return 0;
}

int getans()
{
    preprocess();
    if (sum[n][m]==n*m) return 0;
    l=1;
    r=min(n,m);
    mid=(l+r+1)/2;
    while (l<r)
    {
        if (pd(mid)==1)
            l=mid;
        else
            r=mid-1;
        mid=(l+r+1)/2;
    }
    return mid;
}

int update(int x)
{
    int y;
    for (y=1;y<=m;y++)
    {
        if (map[x][y]=='X') mal[x][y]=0;
        else mal[x][y]=mal[x][y-1]+1;
    }
    for (y=m;y>=1;y--)
    {
        if (map[x][y]=='X') mar[x][y]=0;
        else mar[x][y]=mar[x][y+1]+1;
    }
}

int main()
{
    freopen("read.in","r",stdin);
    scanf("%d%d%d",&n,&m,&k);
    for (i=1;i<=n;i++)
    {
        scanf("%s",map[i]+1);
    }
    for (i=1;i<=k;i++)
    {
        scanf("%d%d",&q[i][1],&q[i][2]);
        map[q[i][1]][q[i][2]]='X';
    }
    ans[k]=getans();
    for (i=1;i<=n;i++)
    {
        update(i);
    }
    for (i=k;i>=1;i--)
    {
        x=q[i][1];
        y=q[i][2];
        map[x][y]='.';
        update(x);
        exl[x]=mal[x][y];
        exr[x]=mar[x][y];
        for (l=x-1;l>=1;l--)
        {
            exl[l]=min(exl[l+1],mal[l][y]);
            exr[l]=min(exr[l+1],mar[l][y]);
        }
        for (r=x+1;r<=n;r++)
        {
            exl[r]=min(exl[r-1],mal[r][y]);
            exr[r]=min(exr[r-1],mar[r][y]);
        }
        r=x;
        for (l=1;l<=x;l++)
        {
            while ((r+1<=n)&&(min(exl[l],exl[r+1])+min(exr[l],exr[r+1])-1>=r-l+1))
            {
                r++;
            }
            if (min(exl[l],exl[r])+min(exr[l],exr[r])-1>=r-l+1)
            ans[i-1]=max(ans[i-1],r-l+1);
        }
        ans[i-1]=max(ans[i-1],ans[i]);
    }
    for (i=1;i<=k;i++)
    {
        printf("%d\n",ans[i]);
    }
}

Guess you like

Origin www.cnblogs.com/leason-lyx/p/11515357.html