zoukankan      html  css  js  c++  java
  • CF1200D White Lines | 前缀和

    传送门

    Examples
    input 1
    4 2
    BWWW
    WBBW
    WBBW
    WWWB
    
    output 1
    4
    
    input 2
    3 1
    BWB
    WWB
    BWB
    
    output 2
    2
    
    input 3
    5 3
    BWBBB
    BWBBB
    BBBBB
    BBBBB
    WBBBW
    
    output 3
    2
    
    input 4
    2 2
    BW
    WB
    
    output 4
    4
    
    input 5
    2 1
    WW
    WW
    
    output 5
    4
    
    Note

    In the first example, Gildong can click the cell(2,2), then the working screen becomes:

    BWWW
    WWWW
    WWWW
    WWWB

    Then there are four white lines — the 2-nd and 3-rd row, and the 2-nd and 3-rd column.

    In the second example, clicking the cell (2,3)makes the 2-nd row a white line.

    In the third example, both the 2-nd column and 5-th row become white lines by clicking the cell (3,2).

    题意:有一个n*n的格子,由'B'和'W'组成,B代表黑色,W代表白色。现在有一个k*k的橡皮擦,你可以选一个地方(i,j)(1≤i≤n-k+1,1≤j≤n-k+1)点击,它会将(i',j')(i≤i'≤i+k-1,j≤j'≤j+k-1)区域全部变为白色,若一行(列)全是W全是W那么这一行(列)就是一条白色的线。现在问你擦一次之后最多能有多少条线。

    题解:我们可以利用前缀和统计每一行每一列有多少个黑格子,前缀和为0表示这一行(列)本来就是一条白线,可以算出初始白线的数量。然后我们一行行一列列判断从这个点开始往右(下)k个变成白色之后会不会增加一条线,再用前缀和记录前n行(列)一共能加几条线。最后枚举每一个可以点击的点看这个区间能增加多少白线更新ans。

    代码:

    #include <bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int N = 2e3 + 10;
    char s[N][N];
    int r[N][N],c[N][N],rr[N][N],cc[N][N];
    int main(){
        int n,k;
        scanf("%d%d",&n,&k);
        for (int i = 1; i <= n; i++)
            scanf("%s",s[i]+1);
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++) {
                r[i][j] = r[i][j-1]+(s[i][j]=='B');
                c[i][j] = c[i][j-1]+(s[j][i]=='B');
            }
        }
        int tot = 0;
        for (int i = 1; i <= n; i++) 
            tot+=(r[i][n] == 0) + (c[i][n] == 0);
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n-k+1; j++) {
                rr[i][j] = rr[i-1][j] + (r[i][j+k-1] - r[i][j-1] == r[i][n] && r[i][n]);
                cc[i][j] = cc[i-1][j] + (c[i][j+k-1] - c[i][j-1] == c[i][n] && c[i][n]);
            }
        }
        int ans = tot;
        for (int i = 1; i <= n-k+1; i++) 
            for (int j = 1; j <= n-k+1; j++)
                ans = max(ans,tot+rr[i+k-1][j]-rr[i-1][j]+cc[j+k-1][i]-cc[j-1][i]);
        printf("%d
    ", ans);
        return 0;
    }
    View Code
  • 相关阅读:
    SQL 获取本年第几周
    SQL Server 数据类型
    (转)经典SQL查询语句大全
    mssql查询某个值存在某个表里的哪个字段的值里面
    SQL Server 数据库还原
    SQL Server 数据库备份
    【转】T-SQL 教程
    【原】C# decimal字符串转成整数
    Django基础篇(二)与mysql配合使用
    Django基础篇(一)
  • 原文地址:https://www.cnblogs.com/l999q/p/11338575.html
Copyright © 2011-2022 走看看