洛谷P1387 最大正方形 题解
P1387 最大正方形 题解
题目
题解
思路
这题可以使用二维前缀和解。(不懂什么是二维前缀和或者不会基本公式的可以先去网上搜一下,这篇文章不会讲基础的哦)
使用\(s\)存\(a\)的二维前缀和,枚举正方形的左上端点,再在内部枚举一个\(p\)代表正方形长度,从\(mxl\)(即当前最大长度,比已知答案更小的没有必要判断,优化时间复杂度)到\(min(n-i+1,m-j+1)\)(因为有可能边长满足其中一边不越界另一边却会越界,所以需要取可以的边长最小值)。
如果一个正方形内的的数全部都不是0(也就是都是1)那么这个正方形内的数和就应为正方形的边长的平方。我们可以利用这一特点结合前缀和判断正方形内是否都是1。
对于每一个可行的边长解,记录下来,最后输出就可以了。
代码
#include<bits/stdc++.h>
#define endl '\n'
using namespace std;
const long long INF = 0x3f3f3f3f;
const double EPS = 1e-8;
const long long N = 105;
int n,m,a[N][N],s[N][N],mxl;
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin>>a[i][j];
s[i][j]=a[i][j]+s[i-1][j]+s[i][j-1]-s[i-1][j-1];//处理前缀和
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
for(int p=mxl+1;p<=min(n-i+1,m-j+1);p++){
int k=i+p-1;
int l=j+p-1;
int c=s[k][l]-s[i-1][l]-s[k][j-1]+s[i-1][j-1];
if(c==p*p){
mxl=max(mxl,p);
}
}
}
}
cout<<mxl<<endl;
return 0;
}

浙公网安备 33010602011771号