题目本身不难 但是要用滚动数组,否则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.