题目
我是按照边进行二分的
class Solution {
public:
int sum[100005];
int a[305][305];
int maxSideLength(vector<vector<int>>& mat, int threshold) {
if(threshold==0)
return 0;
int n = mat.size();
int m = mat[0].size();
int len = min(n,m);
for(int i=0;i<=len;i++)
{
sum[i]=99999999;
}
a[0][0] = mat[0][0];
for(int j=1;j<m;j++)
{
a[0][j] = mat[0][j]+a[0][j-1];
}
for(int i=1;i<n;i++)
{
a[i][0]=mat[i][0]+a[i-1][0];
}
for(int i=1;i<n;i++)
{
for(int j=1;j<m;j++)
{
a[i][j] = a[i-1][j]+a[i][j-1]+mat[i][j] -a[i-1][j-1];
}
}
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
for(int k=0;k<len;k++)
{
int x=99999999;
if(i-k<0||j-k<0)
continue;
if(k==0)
{
x = mat[i][j];
}
else
{
x=a[i][j];
if(i-k-1>=0)
{
x = x-a[i-k-1][j];
}
if(j-k-1>=0)
{
x = x-a[i][j-k-1];
}
if(i-k-1>=0&&j-k-1>=0)
{
x = x+a[i-k-1][j-k-1];
}
}
if(x<=threshold)
{
sum[k+1] = min(sum[k+1],x);
}
}
}
}
int start = 1;
int end = len;
int ans=-1;
while(start<=end)
{
int mid = (start + end)/2;
if(sum[mid]>threshold)
{
end = mid-1;
}
if(sum[mid]<threshold)
{
start = mid+1;
}
if(sum[mid]==threshold)
{
ans=mid;
break;
}
}
if(ans==-1)
{
if(sum[end]>threshold)
ans=0;
else
ans=end;
}
return ans;
}
};