043.二维前缀和+剪枝

尝试用前缀和 + 剪枝通过一些题目

leetcodec 1277

class Solution {
public:
    int countSquares(vector<vector<int>>& matrix) {
        int n=matrix.size(),m=matrix[0].size();
        vector<vector<int>>pre(n+1,vector<int>(m+1));
        for(int i=1;i<=n;++i){
            for(int j=1;j<=m;++j){
                pre[i][j]=matrix[i-1][j-1]+pre[i-1][j]+pre[i][j-1]-pre[i-1][j-1];
            }
        }
        int ans=0;
        for(int i=0;i<n;++i){
            for(int j=0;j<m;++j){
                if(matrix[i][j]==0)continue;
                int a=min(n-i,m-j);
                for(int k=1;k<=a;++k){
                    int x=i+k,y=j+k;
                    int t=pre[x][y]+pre[i][j]-pre[x][j]-pre[i][y];
                    if(t==k*k)ans++;
                    else break;
                }
            }
        }
        return ans;
    }
};

leetcode 1504

class Solution {
public:
    int numSubmat(vector<vector<int>>& mat) {
        int n=mat.size(),m=mat[0].size();
        vector<vector<int>>pre(n+1,vector<int>(m+1));
        for(int i=1;i<=n;++i){
            for(int j=1;j<=m;++j){
                pre[i][j]=mat[i-1][j-1]+pre[i-1][j]+pre[i][j-1]-pre[i-1][j-1];
            }
        }
        int ans=0;
        for(int i=0;i<n;++i){
            for(int j=0;j<m;++j){
                for(int x=i+1;x<=n;++x){
                    for(int y=j+1;y<=m;++y){
                        int s=(x-i)*(y-j);
                        int t=pre[x][y]+pre[i][j]-pre[x][j]-pre[i][y];
                        if(s==t)ans++;
                        else break;
                    }
                }
            }
        }
        return ans;
    }
};

leetcode 221

class Solution {
public:
    int maximalSquare(vector<vector<char>>& matrix) {
        int n=matrix.size(),m=matrix[0].size();
        vector<vector<int>>pre(n+1,vector<int>(m+1));
        for(int i=1;i<=n;++i){
            for(int j=1;j<=m;++j){
                pre[i][j]=pre[i-1][j]+pre[i][j-1]+matrix[i-1][j-1]-'0'-pre[i-1][j-1];
            }
        }
        int ans=0;
        for(int i=0;i<n;++i){
            int a=min(n-i,m);
            if(a*a<=ans)break;
            for(int j=0;j<m;++j){
                int a=min(n-i,m-j);
                if(a*a<=ans)break;
                for(int k=1;k<=a;++k){
                    int x=i+k,y=j+k;
                    int s=pre[i][j]+pre[x][y]-pre[x][j]-pre[i][y];
                    if(s==k*k)ans=max(ans,s);
                }
            }
        }
        return ans;
    }
};

letcode 85

class Solution {
public:
    int maximalRectangle(vector<vector<char>>& matrix) {
        int n=matrix.size(),m=matrix[0].size();
        vector<vector<int>>pre(n+1,vector<int>(m+1));
        for(int i=1;i<=n;++i){
            for(int j=1;j<=m;++j){
                pre[i][j]=pre[i][j-1]+pre[i-1][j]+matrix[i-1][j-1]-'0'-pre[i-1][j-1];
            }
        }
        int ans=0;
        for(int i=0;i<n;++i){
            if((n-i)*m<=ans)break;
            for(int j=0;j<m;++j){
                if((n-i)*(m-j)<=ans)continue;
                for(int x=i+1;x<=n;++x){
                    if((x-i)*(m-j)<=ans)continue;
                    for(int y=j+1;y<=m;++y){
                        int s=(x-i)*(y-j);
                        int sum=pre[x][y]+pre[i][j]-pre[x][j]-pre[i][y];
                        if(s==sum){
                            ans=max(ans,s);
                        }
                        else break;
                    }
                }
            }
        }
        return ans;
    }
};

luogu P2706

#include<bits/stdc++.h>
using namespace std;
const int N=305;
int n,m;
int M[N][N],p[N][N],L[N][N];
void solve(){
    cin>>n>>m;
    for(int i=1;i<=n;++i){
        for(int j=1;j<=m;++j){
            cin>>M[i][j];
            p[i][j]=p[i][j-1]+p[i-1][j]+M[i][j]-p[i-1][j-1];
            L[i][j]=M[i][j]==0?j:L[i][j-1];
        }
    }
    int ans=0;
    for(int i=1;i<=n;++i){
        for(int j=1;j<=m;++j){
            int l=0;
            for(int k=i;k;--k){
                if(M[k][j]==0)break;
                l=max(l,L[k][j]);
                ans=max(ans,p[i][j]+p[k-1][l]-p[i][l]-p[k-1][j]);
            }
        }
    }
    cout<<ans;
}
int main(void){
    cin.tie(0)->sync_with_stdio(0);
    int T=1;
    //cin>>T;
    while(T--)solve();
}
posted @ 2026-01-13 23:47  射杀百头  阅读(4)  评论(0)    收藏  举报