矩阵前缀和:找到窗口的*最多数量

#include<iostream>
#include <vector>
#include<algorithm>
#include<cmath>
#include <climits>
#include<unordered_map>
using namespace std;
typedef long long ll;
#define ret return
#define str string
#define vt vector
#define vti vector<int>
#define forc(s,e) for(int i=s;i<e;i++)
#define fori(i,s,e) for(int i=s;i<e;i++)
#define umap unordered_map
#define vmp(vec, map) do { for (size_t i = 0; i < vec.size(); ++i) { (map)[vec[i]] = i; }} while(0)
#define smp(container, map)for (const auto& item : container) {(map)[item]++;}
#define fora(v) for(auto a:v)
template<typename T>
using vvt = vector<vector<T>>;
#define foreach2(container) for(auto& row : container){ for(auto element : row) if(true) std::cout << element << " "; std::cout << std::endl;}
const ll N=1e16;

void solve(){
    int n,m;cin>>n>>m;
    vvt<char> v(n,vt<char>(n));
    fori(i,0,n){
        fori(j,0,n){
            cin>>v[i][j];
        }
    }
//构造前缀数组
    vvt<int> pre(n,vt<int>(n,0));
    if(v[0][0]=='*'){
        pre[0][0]=1;
    }
    else{
        pre[0][0]=0;
    }
//先处理第一行第一列
    forc(1,n){
        if(v[0][i]=='*'){
            pre[0][i]=pre[0][i-1]+1;
        }
        else{
            pre[0][i]=pre[0][i-1];
        }
    }
    forc(1,n){
        if(v[i][0]=='*'){
            pre[i][0]=pre[i-1][0]+1;
        }
        else{
            pre[i][0]=pre[i-1][0];
        }
    }
//再处理后面的
    fori(i,1,n){
        fori(j,1,n){
            if(v[i][j]=='*'){
                pre[i][j]=pre[i-1][j]+pre[i][j-1]+1-pre[i-1][j-1];
            }
            else{
                pre[i][j]=pre[i-1][j]+pre[i][j-1]-pre[i-1][j-1];
            }
        }
    }
    int ans=INT_MIN;
//枚举所有位置,用O(1)找到每个窗口*的数量,如果直接暴力计算,会在枚举窗口里面的每个字符,会有O(m*m),这个直接用O(1)计算出了数量
    fori(i,0,n-m+1){
        fori(j,0,n-m+1){
            if(i==0&&j==0){
                ans=max(ans,pre[i+m-1][j+m-1]);//为了保证不越界,分情况讨论,其实也可以直接在开数组时,多1行,1列,让元素从下标1开始,这样就不需要多余的情况判断,直接使用最后一个公式。
            }
            else if(i==0&&j!=0){
                ans=max(ans,pre[i+m-1][j+m-1]-pre[i+m-1][j-1]);
            }
            else if(i!=0&&j==0){
                ans=max(ans,pre[i+m-1][j+m-1]-pre[i-1][j+m-1]);
            }
            else{
                ans=max(ans,pre[i+m-1][j+m-1]-pre[i-1][j+m-1]-pre[i+m-1][j-1]+pre[i-1][j-1]);
            }
        }
    }
    cout<<ans;
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    solve();
    ret 0;
}

相关推荐

  1. 矩阵前缀找到窗口*数量

    2024-06-06 15:26:03       8 阅读
  2. [Kadane算法,前缀思想]元素矩阵

    2024-06-06 15:26:03       36 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-06-06 15:26:03       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-06-06 15:26:03       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-06-06 15:26:03       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-06-06 15:26:03       20 阅读

热门阅读

  1. iOS hitTest 机制用处之二-----使用pointInside方法

    2024-06-06 15:26:03       10 阅读
  2. py之每日spider案例分享

    2024-06-06 15:26:03       8 阅读
  3. STM32_SPI

    STM32_SPI

    2024-06-06 15:26:03      8 阅读
  4. 什么是接地电阻柜呢?

    2024-06-06 15:26:03       9 阅读
  5. 解决QT QMessageBox 弹出需点击两次才能关闭问题

    2024-06-06 15:26:03       9 阅读
  6. delphi 3层源码

    2024-06-06 15:26:03       9 阅读
  7. react+vite创建

    2024-06-06 15:26:03       10 阅读