The Escape Plan of Groundhog
原创
©著作权归作者所有:来自51CTO博客作者caoanda的原创作品,请联系作者获取转载授权,否则将追究法律责任
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;
}