洛谷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;
}
posted @ 2025-02-09 17:12  2789617221guo  阅读(135)  评论(0)    收藏  举报