The Escape Plan of Groundhog

J. The Escape Plan of Groundhog

首先这道题肯定只能\(O(n^3)\)来写,暴力来求的话是\(O(n^4)\),那么我们只需要优化一个\(O(n)\)就好了。

优化的方法是用一个枚举子矩形宽的长度,然后再依次遍历每一行,首先要满足要求(两条高上的点需要全是1),下底的点全为1,最后一个是除外面一圈的剩余点是否符合要求,但是每一种不同的情况对应值都不同,直接去查找的复杂度是\(O(n)\)相当于没有优化,所以关键点就是把0变成-1,这样就可以利用前缀和把复杂度降为\(O(1)\)了。

要注意的一点是统计答案用哈希 map 会 tle,需要用一个数组来标记。

// Created by CAD
#include <bits/stdc++.h>
using namespace std;

int a[505][505],x[505][505];
const int maxn=500*500;
int bj[maxn*2+5];
void clear(vector<int> &v){
    for(int i:v)
        bj[i]=0;
}
int main() {
    int n,m;scanf("%d%d",&n,&m);
    for(int i=1;i<=n;++i)
    for(int j=1;j<=m;++j){
        scanf("%d",&a[i][j]);
        if(a[i][j]==0) a[i][j]=-1;
        x[i][j]=x[i][j-1]+a[i][j];
    }
    int ans=0;
    for(int l=1;l<=m;++l)
    for(int r=l+1;r<=m;++r){
        int sum=maxn;
        vector<int> v;
        for(int i=1;i<=n;++i){
            int temp=x[i][r-1]-x[i][l];
            if(r-l+1==2) temp=0;
            sum+=temp;
            if(a[i][l]!=1||a[i][r]!=1) clear(v);
            else if(x[i][r]-x[i][l-1]==r-l+1){
                sum-=temp;
                ans+=bj[sum]+bj[sum-1]+bj[sum+1];
                sum+=temp;
                v.push_back(sum);
                bj[sum]++;
            }
        }
        clear(v);
    }
    printf("%d\n",ans);
    return 0;
}
posted @ 2020-08-09 12:27  caoanda  阅读(146)  评论(0编辑  收藏  举报