最大正方形

Description

  给一个N*N01矩阵, 求一个面积最大的全为1的正方形子矩阵. 输出它的面积.

Input

  输入文件square.in的第一行包含一个正整数N.
  接下来N, 每行N个数, 保证不是0就是1. 每行相邻两个数之间没有空格.

Output

  输出文件为square.out,仅包含一个整数表示最大的全1子正方形矩阵的面积。

Sample Input

2

11

11

Sample Output

4

DataConstraint

Hint

【数据规模和约定】
80%的数据中 N<=250
100%的数据中 N <= 1000

 

分析:

枚举每个点,二分枚举这个点右下(左下)的最大正方形。加一个剪枝优化一下就很快了。

剪枝:一个点右下(左上)的最大正方形是这个点横纵坐标的最小值。如果小于当前的答案,就不必二分了。

 

代码:

 

var
 f:array [0..1001,0..1001] of longint;
 n,i,j,ans,t:longint;
procedure init;
 var ch:char;
     s:ansistring;
begin
 readln(n);
  for i:=1 to n do
   begin
     for j:=1 to n do
      begin
       read(ch);
       if ch='1' then t:=1 else t:=0;
       f[i,j]:=f[i-1,j]+f[i,j-1]-f[i-1,j-1]+t;
      end;
    readln;
  end;
end;

function min(x,y:longint):longint;
 begin
  if x<y then exit(x)
         else exit(y);
 end;

function max(x,y:longint):longint;
 begin
  if x>y then exit(x)
         else exit(y);
 end;

function find(x:longint):longint;
 var l,r,mid,t,t1:longint;
begin
 l:=1; r:=x;
  while l<=r do
   begin
    mid:=(l+r) shr 1;
    if r-l<=1 then break;
    t:=f[i,j]-f[i-mid,j]-f[i,j-mid]+f[i-mid,j-mid];
    if t=mid*mid then l:=mid
                 else r:=mid-1;
   end;
    t:=f[i,j]-f[i-r,j]-f[i,j-r]+f[i-r,j-r];
    t1:=f[i,j]-f[i-l,j]-f[i,j-l]+f[i-l,j-l];
    if t=r*r then exit(r);
    if t1=l*l then exit(l)
              else exit(0);
end;

begin
 init;
  for i:=n downto 1 do
   for j:=n downto 1 do
    begin
     if min(i,j)<ans then continue;
     ans:=max(find(min(i,j)),ans);
    end;
 writeln(ans*ans);
end.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值