【USACO】Big Barn,1997 Fall

题目本身不难 但是要用滚动数组,否则10000*10000的integer会爆128M

考虑记sqrr[i,j] 为以[i,j]为右下角向左上扩展的正方形的最大值,up[i,j]为以[i,j]为最后一格能向上扩展的最大值,left[i,j]同理

则sqrr[i,j]=min(sqrr[i-1,j-1]+1,up[i,j],left[i,j]);

可以看到第i行状态只与i-1行有关

【NOTICE】 j要downto,否则会覆盖前一行数据

边界:对第一行,如果a[i,j]可行则(sqrr[j]=1,left[j]=left[j-1]+1,up[j]=1)否则均为0

由于算min值要用到当前行的up,left,所以处理每一行前先更新up和left,然后j递减来推sqrr

 1 var
 2    n,m,i,j,x,y,max:integer;
 3    a:array[0..10001,0..10001] of boolean;
 4    up,sqrr,left:{array[0..10001,0..10001] of integer;} array[0..10001] of integer;
 5 function min(a,b,c:integer):integer;
 6 begin
 7    if (a<=b)and(a<=c) then exit(a);
 8    if (b<=c)and(b<=a) then exit(b);
 9    exit(c);
10 end;
11 begin
12    assign(input,'bigbrn.in');
13    reset(input);
14    assign(output,'bigbrn.out');
15    rewrite(output);
16    readln(n,m);
17    fillchar(a,sizeof(a),true);
18    fillchar(up,sizeof(up),0);
19    for i:=1 to m do
20    begin
21       readln(x,y);
22       a[x,y]:=false;
23    end;
24 
25    for i:=1 to n do if a[1,i] then
26    begin
27       left[i]:=left[i-1]+1;
28       sqrr[i]:=1;
29       up[i]:=1;
30       if sqrr[i]>max then max:=sqrr[i];
31    end;
32 
33    for i:=2 to n do
34    begin
35 
36       for j:=1 to n do
37       if a[i,j] then
38       begin
39         inc(up[j]);
40         left[j]:=left[j-1]+1;
41       end else
42       begin
43          up[j]:=0;left[j]:=0;
44       end;
45 
46       for j:=n downto 2 do
47       if a[i,j]  then
48       begin
49          sqrr[j]:=min(sqrr[j-1]+1,left[j],up[j]);
50          if sqrr[j]>max then max:=sqrr[j];
51 
52       end   else sqrr[j]:=0;
53       if a[i,1] then sqrr[1]:=1 else sqrr[1]:=0;
54    end;
55 
56    writeln(max);
57    close(input);
58    close(output);
59 end.

 

posted @ 2013-09-23 12:38  OmegaIota  阅读(200)  评论(0编辑  收藏  举报