————————————本文旨在讨论交流计算机知识,欢迎指正—————————————
看到此题,笔者的第一印象就是正方形和边长,之间有开方的关系。
既然题目给了1是正方形的判定指标 ,那么思路也就很简单了,如果某一块的和开方和边长相等即满足题目要求,用max(x,y)来更新边长;
如此,我们首先想到的方法即二维前缀和:
cin>>n>>m;
int a[n][m];
int pre[n][m];
for(int i=0;i<n;i++)//输入每个格子的数字
{
for(int j=0;j<m;j++)
{
cin>>a[i][j];
}
}
for(int i=0;i<n;i++)pre[i][0]=a[i][0];//初始化二位前缀和
for(int j=0;j<m;j++)pre[0][j]=a[0][j];//同上
for(int i=1;i<n;i++)
{
for(int j=1;j<m;j++)
{
pre[i][j]=a[i][j]+pre[i-1][j]+pre[i][j-1]-pre[i-1][j-1];//构造二维前缀和
}
}
下一步,则是边长的匹配了:
这里笔者选用枚举法,即枚举边长,如果满足则更新记录res答案,并l++,继续枚举看是否成功,如果满足则再次自增和更新记录......
上代码:
int res=0;
int l=1;
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
if(pre[i][j]-pre[i-l][j]-pre[i][j-l]+pre[i-l][j-l]==l*l)//判断(i,j)是否可以形成l边长的正方形;(不用担心会遗漏,如果l-1满足而l不满足,前面l++的时候res已经记录了l-1可行了,就不用在试l-1行不行,这样浪费时间空间)
{
res=max(res,l);//更新res
l++;//继续枚举
}
}
}
最后输出res即可;
下面附上完整代码:
#include<bits/stdc++.h>
using namespace std;
int n,m;
int main()
{
cin>>n>>m;
int a[n][m];
int pre[n][m];
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
cin>>a[i][j];
}
}
for(int i=0;i<n;i++)pre[i][0]=a[i][0];
for(int j=0;j<m;j++)pre[0][j]=a[0][j];
for(int i=1;i<n;i++)
{
for(int j=1;j<m;j++)
{
pre[i][j]=a[i][j]+pre[i-1][j]+pre[i][j-1]-pre[i-1][j-1];
}
}
int res=0;
int l=1;
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
if(pre[i][j]-pre[i-l][j]-pre[i][j-l]+pre[i-l][j-l]==l*l)
{
res=max(res,l);
l++;
}
}
}
cout<<res<<endl;
return 0;
}
希望能对你有所帮助!