题意:给你一个n*m的矩阵,矩阵元素只有0和1,求矩阵中最大的正方形,正方形中最多只能有1个1
思路:先对矩阵做一个二维前缀和,然后二分正方形的边长,这题数据很水,但及其毒瘤的是,必须得有输入挂才能过,不然就会T,我不用输入挂T了,用了之后134ms。。。。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <stack>
#include<set>
using namespace std;
#define maxn 1050
int mp[maxn][maxn],s[maxn][maxn];
int n,m;
int flagi;
inline int read(){
int x=0; bool f=0; char ch=getchar();
while (ch<'0' || '9'<ch) f|=ch=='-', ch=getchar();
while ('0'<=ch && ch<='9') x=x*10+ch-'0', ch=getchar();
return f?-x:x;
}
bool check(int x)
{
int s1=0;
for(int i=flagi;i+x-1<=n;i++)
{
for(int j=1;j+x-1<=m;j++)
{
s1=s[i+x-1][j+x-1]-s[i+x-1][j-1]-s[i-1][j+x-1]+s[i-1][j-1];
if(s1<=1){
flagi=i;
return true;
}
}
}
return false;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
flagi=1;
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
//mp[i][j]=rand()%2;
mp[i][j]=read();
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
s[i][j]=s[i-1][j]+s[i][j-1]-s[i-1][j-1]+mp[i][j];
//printf("s[%d][%d]=%d ",i,j,s[i][j]);
}
//printf("\n");
}
int l=1,r=min(n,m),ans=0;
while(l<=r)
{
int mid=(l+r)>>1;
if(check(mid))
{
l=mid+1;
ans=mid;
}
else r=mid-1;
}
printf("%d\n",ans);
}
}
/*
2
10 20
0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 1 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
20 10
1 0 0 0 0 1 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 1 0
0 0 1 0 0 0 0 1 1 0
0 0 0 0 0 0 0 0 0 1
0 0 0 0 0 0 0 0 0 1
0 0 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 1 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 1 0 0 0 1 0 0 0
0 0 0 0 0 0 0 0 0 0
*/