bzoj 1057 悬线法

61 篇文章 0 订阅
3 篇文章 0 订阅

题意:n*m的棋盘,求出满足像国际象棋棋盘那样黑白相间的最大子矩阵和最大正方形

经典悬线法

一开始直接按01的情况上的裸悬线法,经亲测,所得最大正方形的答案是正确的,但是最大子矩阵的答案偏小

然后网上的大神教我做人...orz

把奇行偶列和偶行奇列位置的取反,就能把它转化为普通的求全1或全0的一般悬线法,

分别以0为障碍点和以1位障碍点跑一遍,取max

var
        n,m             :longint;
        ans1,ans2       :longint;
        map             :array[0..2010,0..2010] of longint;
        i,j             :longint;
        l,r,h           :array[0..2010,0..2010] of longint;
function min(a,b:longint):longint;
begin
   if a<b then exit(a) else exit(b);
end;

function max(a,b:longint):longint;
begin
   if a<b then exit(b) else exit(a);
end;

procedure work(x:longint);
var
        i,j:longint;
        tt:longint;
begin
   fillchar(h,sizeof(h),0);
   fillchar(l,sizeof(l),0);
   fillchar(r,sizeof(r),0);
  //
   for i:=1 to n do
   begin
      for j:=1 to m do
        if (map[i,j]<>x) then l[i,j]:=0 else l[i,j]:=l[i,j-1]+1;
      for j:=m downto 1 do
        if (map[i,j]<>x) then r[i,j]:=0 else r[i,j]:=r[i,j+1]+1;
   end;
   //
   for i:=2 to n do
     for j:=1 to m do
       if (map[i,j]=x) and (map[i-1,j]=x) then
       begin
          h[i,j]:=h[i-1,j]+1;
          l[i,j]:=min(l[i,j],l[i-1,j]);
          r[i,j]:=min(r[i,j],r[i-1,j]);
       end;
   //
   for i:=1 to n do
     for j:=1 to m do
       ans1:=max(ans1,(h[i,j]+1)*(l[i,j]+r[i,j]-1));
   for i:=1 to n do
     for j:=1 to m do
     begin
        tt:=min(h[i,j]+1,l[i,j]+r[i,j]-1);
        ans2:=max(ans2,tt*tt);
     end;
end;

begin
   read(n,m);
   for i:=1 to n do
     for j:=1 to m do read(map[i,j]);
    for i:=1 to n do
     for j:=1 to m do
       if ((i+j) and 1=1) then map[i,j]:=map[i,j] xor 1;
   work(0);
   work(1);
   writeln(ans2);
   writeln(ans1);
end.
——by Eirlys

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值