解题报告 keke 的房子

 

1.        题目

                Keke的房子

Description

keke得到了一块n*m的土地,他灰常高兴,于是他想要盖个房子,keke的房子必须是正方形的。

但是,并不是土地的每个地方都能盖房子。地面上有一些地方不能盖一砖一瓦。

他当然希望将房子盖得大一些,房子越大就越舒服(有道理没有?)。

于是他又来恶心你了……

Input

输入文件第一行为两个整数n,m(1<=n,m<=1000),接下来n行,每行m个数字,用空格隔开。0表示该块土地不能盖房子,1表示该块土地完好。

Output

一个整数,为keke能盖出的最大正方形房子的边长

Sample Input

4 4

0 1 1 1

1 1 1 0

0 1 1 0

1 1 0 1

Sample Output

2

数据范围

对于30%的数据 n,m<=100

对于100%的数据 n,m<=1000

 

2.        题目实质

找一个指定区域内,不经过指定区域的最大的正方形的边长。

3.        算法

动态规划。

其实这个题还有一个更难的三角形版,也是需要从邻近的几个方向进行转移。

f[I,j] 存右下点为 I,j 的最大的正方形的边长,然后由画图 + 手模(手工模拟)得,最大正方形的边长应为与该格子左边相邻、上边相邻,或是与他的左上顶点相切的三个正方形中最小的那个的边长 + 1

然后,就实现就行了。

然后三角形版是需要从三个方向取最小的进行转移,然后走一遍正三角形,走一遍倒三角形。

4.        注意事项

这个题一定要动态规划,搜索最后两个点超时。

这个题的手模略。

5.        程序代码

FHAI  Pascal

var

f,a:array[0..1003,0..1003]of longint;

ans,tt,n,i,j,m:longint;

function min(a,b:longint):longint;

begin

if a<b then exit(a);

exit(b);

end;

begin

assign(input,'house.in');reset(input);

assign(output,'house.out');rewrite(output);

readln(n,m);

for i:=1to n do

     begin

     for j:=1 to m do

          read(a[i,j]);

     readln;

     end;

for i:=1 to n do

     for j:=1 to n do

     if a[i,j]=1 then

          begin

          tt:=min(f[i,j-1],f[i-1,j]);

          tt:=min(tt,f[i-1,j-1]);

          f[i,j]:=tt+1;

          if f[i,j]>ans then ans:=f[i,j];

          end;

write(ans);

close(input);close(output);

end.

原文地址:https://www.cnblogs.com/SueMiller/p/2136258.html