cf1200 D White Lines(二维差分)

题目大意

有一个大小为n的矩阵,每个1*1的单位为黑或白,我们可以用一个(只有一个)大小为k*k的白色矩阵覆盖,问:最多的时候有几条白线(横的全为白 或竖的全为白 即为白线)。

思路

要想把一条线(以横的为例)全变为白的,那么我们就需要从这一行最左边的黑色块覆盖到最右边的黑色块,如果两端距离超过k,则无法覆盖,否则就一定可以。那么就一定会产生一个矩阵,选取这个矩阵里面的任何一个点 都可以将这行变为白线;反之,矩阵外的一定不行。所以,可以用差分数组,因为只要选了矩阵里的点,答案就一定就加一。然后二维前缀和,最后max取答案。

代码

#include <stdio.h>
#include <queue>
#include <string>
#include <string.h>
#include <algorithm>
#include <math.h>
using namespace std;
typedef long long int ll;
const int maxn = 2e3 + 10;
const ll inf = 0x3f3f3f3f;
int res[maxn][maxn];
char mp[maxn][maxn];
int main()
{
    int n,k,ans,anss;
    while(scanf("%d%d",&n,&k) != EOF){
        for(int i = 1;i <= n;i++)
            scanf("%s",mp[i] + 1);
        memset(res,0,sizeof(res));
        ans = anss = 0;

        for(int i = 1;i <= n;i++){
            int mi = n + 1,mx = 0;
            for(int j = 1;j <= n;j++){
                if(mp[i][j] == ‘B‘){
                    mi = min(j,mi);
                    mx = max(j,mx);
                }
            }
            if(mx == 0){
                anss++;
                continue;
            }
            if(mx - mi + 1 > k)
                continue;
            res[max(i - k + 1,1)][max(mx - k + 1,1)]++;
            res[max(i - k + 1,1)][mi + 1]--;
            res[i + 1][max(mx - k + 1,1)]--;
            res[i + 1][mi + 1]++;
        }
        for(int i = 1;i <= n;i++){
            int mi = n + 1,mx = 0;
            for(int j = 1;j <= n;j++){
                if(mp[j][i] == ‘B‘){
                    mi = min(j,mi);
                    mx = max(j,mx);
                }
            }
            if(mx == 0){
                anss++;
                continue;
            }
            if(mx - mi + 1 > k)
                continue;
            res[max(mx - k + 1,1)][max(i - k + 1,1)]++;
            res[mi + 1][max(i - k + 1,1)]--;
            res[max(mx - k + 1,1)][i + 1]--;
            res[mi + 1][i + 1]++;
        }

        for(int i = 1;i <= n;i++){
            for(int j = 1;j <= n;j++){
                res[i][j] += res[i - 1][j] + res[i][j - 1] - res[i - 1][j - 1];
                ans = max(ans,res[i][j]);
            }
        }

        printf("%d\n",ans + anss);
    }
    return 0;
}

原文地址:https://www.cnblogs.com/InitRain/p/12293595.html

时间: 2024-10-14 06:24:41

cf1200 D White Lines(二维差分)的相关文章

二维差分

二维差分和一维差分思路上并没有什么区别,具体实现的区别就在于一维的直接对区间两端差分就好了,而二维的多了一维需要处理. 差分的思想是和前缀和有关的,一维的前缀和我们都懂求,那么二维的呢? 如图 因为是从左到右,从上到下的遍历,当要求红色部分,(0,0)到(i,j)处的前缀和时,我们黄色部分和蓝色部分已经是已知的了,而它们重叠的部分就是绿色部分,所以把黄色和蓝色部分的结果加起来,再减去绿色部分,最后加上(i,j)处的值就是(i,j)位置的前缀和了. 所以,二维前缀和就是sum[i][j]=a[i]

Gym 102028J 扫描线/二维差分 + 解方程

题意:有一个二维平面,以及n个操作,每个操作会选择一个矩形,使得这个二维平面的一部分被覆盖.现在你可以取消其中的2个操作,问最少有多少块地方会被覆盖? 思路:官方题解简洁明了,就不细说了:https://codeforces.com/blog/entry/63729. 此处重点记录一下两种做法的巧妙之处. 1:二维差分+解方程 二维差分:假设在矩形[(x1, y1), (x2, y2)]上加一个数,那么在(x1, y1), (x2 + 1, y2 + 1)加1, (x1, y2 + 1), (x

Codeforces Round #578 (Div. 2) 二维差分 可做模板

题意: 在n*n的矩阵中,你可以选择一个k*k的子矩阵,然后将这个子矩阵中的所有B全部变为W,问你怎么选择这个子矩阵使得最终的矩阵中某一行全是W或者某一列全是W的个数最多 题解:考虑每一行和每一列,对于特定的一行来说,要想让其全变为W,那么子矩阵的左上角端点是在一个范围中的,因此我们可以把范围中的每一个值加1 为了速度选择用二维差分来做,最终矩阵中的最大值就是答案 此题可以作为二维差分模板 #include<bits/stdc++.h> #define forn(i, n) for (int

二维差分前缀和——cf1202D(好题)

直接枚举每个点作为左上角是可以做的,但是写起来较麻烦 有一种较为简单的做法是对一列或一行统计贡献 比如某一行的B存在的区间是L,R那么就有三种情况 1.没有这样的区间,即一行都是W,此时这行对答案的贡献一直是1 2.R-L+1<=k,那么这一段必须要找一个点代表的矩形来覆盖,可以求出这样的点的存在区间是一个矩形,当且仅当点在这个矩形范围内时,这一行会有1的贡献. 3.R-L+1>k,永远不会有贡献 对于情况2,我们用二维的差分来统计一下,最后枚举每个点,看我们选择这个点代表的矩形时,贡献是否达

一维差分和二维差分

差分 一维: 原数组:\(c[i]\) 差分数组\(a[i]\):表示\(i{\sim}n\)的数,每一个数\(c[j](i<=j<=n)\)都加上一个\(a[i]\) 应用场景: ①把从第\(k-n\)位的数都加上一个\(w\) a[k]+=w; ②把从第\(i\)位到第\(j\)位的数都加上一个\(w\) a[i]+=w,a[j+1]-=w; 前提是需要对数组,进行多次①②这样的操作,使用差分才有意义,不然直接暴力就可以了 要注意的是①②操作只是把那些加减操作缓存了起来,而并不是完全分布给

Problem 3 二维差分

$des$ 考虑一个 n ∗ n 的矩阵 A,初始所有元素均为 0.执行 q 次如下形式的操作: 给定 4 个整数 r,c,l,s, 对于每个满足 x ∈ [r,r+l), y ∈ [c,x−r+c]的元素 (x,y),将权值增加 s.也就是,给一个左上顶点为 (r,c).直角边长为 l 的下三角区域加上 s.输出最终矩阵的元素异或和. $sol$ 每次加减是一个等腰直角三角形 考虑对每行查分 即对垂直于 x 轴的腰上的每个点 +1 ,所有斜边的后一个点 -1 这样的话,每行形成了查分数组 简化

Java生成微信二维码及logo二维码

依赖jar包 QrCode.jar:https://pan.baidu.com/s/1c1PYV0s 加入本地 maven: mvn install:install-file -Dfile=QRCode.jar -DgroupId=QRCode -DartifactId=QRCode -Dversion=3.0 -Dpackaging=jar 实例源码 import com.swetake.util.Qrcode; import javax.imageio.ImageIO; import jav

C#使用ThoughtWorks.QRCode.dll生成二维码以及解码

最近一段时间在网上找了二维码的生成代码,但是生成的二维码右上角的背景色总是透明的,所以自己拿过来改了一下,给自己做个总结. 代码如下: using System;using System.Collections.Generic;using System.Drawing;using System.Linq;using System.Text;using System.Threading.Tasks;using ThoughtWorks.QRCode.Codec;using ThoughtWorks

Python3使用qrcode生成二维码教程

一.安装依赖库 pip install qrcode pillow image pillow是python3中PIL的代替库,image是生成图版需要用到的库 安装image时报错"Could not install packages due to an EnvironmentError: [Errno 22] invalid mode ('wb') or filename",没管,直接在pycharm的setting中安装就没报错了. 二.简单用法 以下是生成指向百度的二维码为例,用