zoukankan      html  css  js  c++  java
  • Codeforces Round #356 (Div. 1) C. Bear and Square Grid

    C. Bear and Square Grid
    time limit per test
    3 seconds
    memory limit per test
    256 megabytes
    input
    standard input
    output
    standard output

    You have a grid with n rows and n columns. Each cell is either empty (denoted by '.') or blocked (denoted by 'X').

    Two empty cells are directly connected if they share a side. Two cells (r1, c1) (located in the row r1 and column c1) and (r2, c2) areconnected if there exists a sequence of empty cells that starts with (r1, c1), finishes with (r2, c2), and any two consecutive cells in this sequence are directly connected. A connected component is a set of empty cells such that any two cells in the component are connected, and there is no cell in this set that is connected to some cell not in this set.

    Your friend Limak is a big grizzly bear. He is able to destroy any obstacles in some range. More precisely, you can choose a square of size k × k in the grid and Limak will transform all blocked cells there to empty ones. However, you can ask Limak to help only once.

    The chosen square must be completely inside the grid. It's possible that Limak won't change anything because all cells are empty anyway.

    You like big connected components. After Limak helps you, what is the maximum possible size of the biggest connected component in the grid?

    Input

    The first line of the input contains two integers n and k (1 ≤ k ≤ n ≤ 500) — the size of the grid and Limak's range, respectively.

    Each of the next n lines contains a string with n characters, denoting the i-th row of the grid. Each character is '.' or 'X', denoting an empty cell or a blocked one, respectively.

    Output

    Print the maximum possible size (the number of cells) of the biggest connected component, after using Limak's help.

    Examples
    input
    5 2
    ..XXX
    XX.XX
    X.XXX
    X...X
    XXXX.
    output
    10
    input
    5 3
    .....
    .XXX.
    .XXX.
    .XXX.
    .....
    output
    25
    Note

    In the first sample, you can choose a square of size 2 × 2. It's optimal to choose a square in the red frame on the left drawing below. Then, you will get a connected component with 10 cells, marked blue in the right drawing.

    炸掉任意一个k*k的矩阵内所有方块,然后问炸完最大的联通块的最大值。

    n*n枚举我现在要炸哪个矩阵,由于每次枚举是把矩阵右移一位,我们可以考虑利用上次的信息。

    (我都扯了些什么鬼……

    反正就是每次删掉一列的信息,增加一列的信息而已。

    预处理出原先的联通块,然后开个桶记录一下每个联通块被我现在的矩形覆盖的点数,当这个点数从0加到1时就给答案累计上这个联通块的大小,从1减到0就扔掉就好了。

    #include<queue>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int read_p,read_ca;
    inline int read(){
        read_p=0;read_ca=getchar();
        while(read_ca<'0'||read_ca>'9') read_ca=getchar();
        while(read_ca>='0'&&read_ca<='9') read_p=read_p*10+read_ca-48,read_ca=getchar();
        return read_p;
    }
    const int f[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
    int n,K,map[502][502],nm=0,t[150000],mmh,MMH=0,nu[150000];
    char c[501];
    struct na{
        int x,y;
        na(int _x,int _y):x(_x),y(_y){}
    };
    queue<na> q;
    inline void bfs(int x,int y){
        register int i;
        map[x][y]=++nm;
        q.push(na(x,y));
        while (!q.empty()){
            nu[nm]++;
            na k=q.front();q.pop();
            for (i=0;i<4;i++)
            if (map[k.x+f[i][0]][k.y+f[i][1]]==0) map[k.x+f[i][0]][k.y+f[i][1]]=nm,q.push(na(k.x+f[i][0],k.y+f[i][1]));
        }
    }
    int main(){
        register int i,j,k;
        n=read();K=read();
        for (i=1;i<=n;i++){
            scanf("%s",c);
            for (j=1;j<=n;j++) map[i][j]=c[j-1]=='X'?-1:0;
        }
        for (i=1;i<=n;i++) map[i][0]=map[i][n+1]=-1;
        for (j=1;j<=n;j++) map[0][j]=map[n+1][j]=-1;
        for (i=1;i<=n;i++)
        for (j=1;j<=n;j++) if (map[i][j]==0) bfs(i,j);
        for (i=1;i<=n-K+1;i++){
            memset(t,0,sizeof(t));mmh=0;
            for (j=i;j<i+K;j++)
            for (k=1;k<=K;k++) if (map[j][k]==-1) mmh++;else{
                if ((++t[map[j][k]])==1) mmh+=nu[map[j][k]];
            }
            for (k=1;k<=K;k++){
                if (map[i-1][k]!=-1) if ((++t[map[i-1][k]])==1) mmh+=nu[map[i-1][k]];
                if (map[i+K][k]!=-1) if ((++t[map[i+K][k]])==1) mmh+=nu[map[i+K][k]];
            }
            for (j=i;j<i+K;j++)
            if (map[j][K+1]!=-1) if ((++t[map[j][K+1]])==1) mmh+=nu[map[j][K+1]];
            if (mmh>MMH) MMH=mmh;
            for (k=1;k<=n-K;k++){
                for (j=i;j<i+K;j++){
                    if (map[j][k+K]==-1) mmh++;
                    if (map[j][k+K+1]!=-1) if ((++t[map[j][k+K+1]])==1) mmh+=nu[map[j][k+K+1]];
                    if (map[j][k]==-1) mmh--;
                    if (map[j][k-1]!=-1) if ((--t[map[j][k-1]])==0) mmh-=nu[map[j][k-1]];
                }
                if (map[i-1][k+K]!=-1) if ((++t[map[i-1][k+K]])==1) mmh+=nu[map[i-1][k+K]];
                if (map[i-1][k]!=-1) if ((--t[map[i-1][k]])==0) mmh-=nu[map[i-1][k]];
                if (map[i+K][k+K]!=-1) if ((++t[map[i+K][k+K]])==1) mmh+=nu[map[i+K][k+K]];
                if (map[i+K][k]!=-1) if ((--t[map[i+K][k]])==0) mmh-=nu[map[i+K][k]];
                if (mmh>MMH) MMH=mmh;
            }
        }
        printf("%d
    ",MMH);
    }
    View Code
  • 相关阅读:
    asp.net textbox控件readonly为true时,后台取值的问题
    未能加载文件或程序集“ICSharpCode.SharpZipLib, Version=0.86.0.518, Culture=neutral, PublicKeyToken=1b03e6acf1164f73”或它的某一个依赖项
    DataSet与DataReader的比较
    EntityFramwork所有 SSDL 项目都必须以同一提供程序为目标。ProviderManifestToken“2008”不同于以前遇到的“2005”
    路由器wan口连接不上的问题
    Git学习(四)----版本号跳转
    jquery记分牌的插件
    ORACLE 第4节 多表查询
    基于消息机制的异步架构之回调函数注冊
    干货!手把手教你怎样高速了解一个行业--游戏产业概况
  • 原文地址:https://www.cnblogs.com/Enceladus/p/5573727.html
Copyright © 2011-2022 走看看