zoukankan      html  css  js  c++  java
  • CF1200D White Lines

    题目链接
    万恶的多校,今天又自闭了,一个题交了18发wa,心态炸裂
    到现在回头补,才写出来。
    题目意思:一个nn的大矩阵,这个大矩阵,只包含 ‘W’ 和 ‘B’ 两种字母, 现在,你只能选择一个 kk 的小矩阵,将这个小矩阵中的字母全部变成 ‘W’ 之后,这个大矩阵的整行,整列全部是 ‘W’ 的个数最多, 求这个数。

    做法:以样例一来说事

    4 2
    BWWW
    WBBW
    WBBW
    WWWB

    首先,我们先只考虑一个方向的一行
    横向
    如图,对于第二行只有满足这个的一个条件 sum(1,i-k) + sum(i+1,n) + k == n, 取矩形时包含这行(或列)才会对答案有贡献
    同样, 对于一列也差不多是这样
    再来,对于整个大矩阵
    整个矩阵
    我们不是要找个 k*k 的矩阵吗, 我们看向上图中矩阵的右下角
    单单只看这个点**(i, j)**
    对于 x 方向 sum(1, j-k) + sum(j+1,n) + k == n 第一个答案
    对于 y 方向 sum(1, i-k) + sum(i+1,n) + k == n 第二个答案

    再来看右下角的上一个点 (i-1,j)
    对于 x 方向 满足条件 第三个答案
    对于 y 方向 如果把这个考虑进去,不会重复吗

    再来看右下角的左边一个点 (i,j-1)
    同样 对于 x 方向 我们不能考虑进去
    对于 y 方向 满足条件 第四个答案

    对于这个2*2的矩阵的最后一个点 (i-1,j-1)
    我们要考虑吗???

    这样的一顿思考后,我们就找到了一种做法,枚举每个矩阵,我们只要考虑这个矩阵的右下角的 x,y 方向, 右下角的正上方的那些点的 x 方向, 右下角的正左方的 y 方向

    但是,按这样的想法去写的话,样例2是过不了的 放心不是我的想法错误

    会发现,有些行或者列, 即使我们不去改,它们也早就都是 ‘W’ 了,所以我们要统计一下


    以上这些想法怎么实现呢,前缀和, 全部都是前缀和

    代码:

    #include <bits/stdc++.h>
    const int maxn = 2005;
    using namespace std;
    typedef long long ll;
    
    int n, k;
    char str[maxn][maxn];
    int yuanx[maxn][maxn], yuany[maxn][maxn];	//统计x  y 方向的前缀和
    int ansx[maxn][maxn], ansy[maxn][maxn];		
    //统计每个点  x 方向的前缀和, 但是这个前缀和要延 y 方向求前缀和
    //统计每个点  y 方向的前缀和, 但是这个前缀和要延 x 方向求前缀和
    int yix[maxn], yiy[maxn];
    //最没改变时, x方向 就都是 'W'
    //最没改变时, y方向 就都是 'W'
    int main()
    {
    	scanf("%d%d", &n, &k);
    	for(int i=1; i<=n; i++){
    		scanf("%s", str[i]+1);
    		for(int j=1; j<=n; j++){
    			yuanx[i][j] = yuanx[i][j-1];
    			yuany[i][j] = yuany[i-1][j];
    			if(str[i][j] == 'W')
    				yuanx[i][j]++, yuany[i][j]++;	//统计前缀和
    		}
    	}
    
    	for(int i=1; i<=n; i++){
    		yix[i] = yix[i-1], yiy[i] = yiy[i-1];
    		if(yuanx[i][n] == n)	//不改变,i行就已经都是白色的
    			yix[i]++;
    		if(yuany[n][i] == n)	//不改变,i列就已经都是白色的
    			yiy[i]++;
    	}
    	int res = 0;
    	for(int i=1; i<=n; i++){
    		for(int j=1; j<=n; j++){
    			ansx[i][j] = ansx[i-1][j];		//x 向的答案向y方向延续
    			ansy[i][j] = ansy[i][j-1];
    			if(j >= k && yuanx[i][j-k] + (yuanx[i][n]-yuanx[i][j]) + k == n)
    				ansx[i][j]++;
    			if(i >= k && yuany[i-k][j] + (yuany[n][j]-yuany[i][j]) + k == n)
    				ansy[i][j]++;
    			if(i >= k && j >= k){
    				int t = ansx[i][j]- ansx[i-k][j] + ansy[i][j] - ansy[i][j-k];	//与改变才产生的答案
    				t = t + yix[n] - (yix[i] - yix[i-k]) + yiy[n] - (yiy[j] - yiy[j-k]);	//这个矩阵,之外,不改变也会增加答案
    				res = max(res, t);
    
    			}
    		}
    	}
    	printf("%d
    ", res);
        return 0;
    }
    
    
  • 相关阅读:
    转:wap1.1和wap2.0的比较~
    转:alidateRequest=false 在.Net 4.0 中不管用
    ASP.NET页面实时进行GZIP压缩优化
    转:WAP1.0 和 WAP2.0 支持的标签区别
    [转载]利用vs.net快速开发windows服务(c#)
    CSS3选择器
    AD10 多层板设计错误解决
    ASP如何获取客户端真实IP地址
    javascript模拟滚动条实现代码(3)
    最近工作中的小细节
  • 原文地址:https://www.cnblogs.com/jizhihong/p/13337335.html
Copyright © 2011-2022 走看看