L:Largest Allowed Area
我是记录前缀方形数组sum[i][j]表示前i行和前j列这个方形内数字总和。
然后就可以用这个表示出第i,j点,边长。n的方形中间的数的和。
如果小于1等于就满足。
这里有点奇怪。。。用一般的输入挂982ms(就是我注释的),
用高级挂。。。171ms。。。卧槽。。???
好像有单调队列的做法,等会看了补上。
#include<bits/stdc++.h>
#define maxn 1010
using namespace std;
int qi[maxn][maxn];
int s[maxn][maxn];
/*template<typename T>
inline T read(T&x)
{ x = 0;int f = 1; char ch = getchar();
while(ch<'0' || ch>'9') { if(ch == '-') f=-1; ch=getchar(); }
while(ch>='0' && ch<='9') { x=x*10+ch-'0'; ch=getchar(); }
return x*f;
}*/
namespace fastIO {
#define BUF_SIZE 100000
//fread -> read
bool IOerror = 0;
inline char nc() {
static char buf[BUF_SIZE], *p1 = buf + BUF_SIZE, *pend = buf + BUF_SIZE;
if(p1 == pend) {
p1 = buf;
pend = buf + fread(buf, 1, BUF_SIZE, stdin);
if(pend == p1) {
IOerror = 1;
return -1;
}
}
return *p1++;
}
inline bool blank(char ch) {
return ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t';
}
inline void read(int &x) {
char ch;
while(blank(ch = nc()));
if(IOerror) return;
for(x = ch - '0'; (ch = nc()) >= '0' && ch <= '9'; x = x * 10 + ch - '0');
}
#undef BUF_SIZE
};
using namespace fastIO;
int main()
{
int t;
cin>>t;
while(t--)
{
int n,m,cnt=0,mnum=0;
//n=read();
read(n);
//m=read();
read(m);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
read(s[i][j]);
//s[i][j]=read();
// scanf("%d",&s[i][j]);
qi[i][j]=qi[i-1][j]+qi[i][j-1]-qi[i-1][j-1]+s[i][j];
}
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
int l=mnum,r=min(n-i+1,m-j+1);
if(mnum>=r)
continue;
while(l<=r)
{
int mid=(l+r)/2;
if(qi[i+mid-1][j+mid-1]-qi[i-1][j+mid-1]-qi[i+mid-1][j-1]+qi[i-1][j-1]<=1)
l=mid+1,cnt=mid;
else
r=mid-1;
}
//printf("%d ",cnt);
if(mnum<cnt)
mnum=cnt;
}
printf("%d\n",mnum);
}
return 0;
}