算法:DP
分析:跟USACO上的某道题基本上就是完全相同。
首先是初始化,对于是'-'的预处理为1,否则预处理为0。
用f[i,j]表示(i,j)这个点的最大的三角形的侧边长,每个点由左上、上、右上三个点转移而来,取一个最小值+1,同时必须满足三个点都不是'#',否则依然为1。
先处理冲上的三角形,然后处理冲下的三角形。
分析:跟USACO上的某道题基本上就是完全相同。
首先是初始化,对于是'-'的预处理为1,否则预处理为0。
用f[i,j]表示(i,j)这个点的最大的三角形的侧边长,每个点由左上、上、右上三个点转移而来,取一个最小值+1,同时必须满足三个点都不是'#',否则依然为1。
先处理冲上的三角形,然后处理冲下的三角形。
最后只有顶点是当前行的奇数列的才能成为三角形的顶点,所以还需要特别判断一下。
program Vijos1063;
const
maxn=300;
var
n,ans:longint;
a:array [0..maxn,0..maxn] of char;
f,ff:array [0..maxn,0..maxn] of longint;
procedure init;
var
i,j:longint;
begin
fillchar(f,sizeof(f),0);
fillchar(ff,sizeof(ff),0);
ans:=0;
readln(n);
for i:=1 to n do
begin
for j:=1 to (n shl 1)-i do
begin
read(a[i,j]);
if a[i,j]='-' then
begin
f[i,j]:=1;
ff[i,j]:=1;
end
else a[i,j]:='#';
end;
for j:=(n shl 1)-i+1 to (n shl 1)-1 do a[i,j]:='#';
readln;
end;
end;
function min(x,y:longint):longint;
begin
if x<y then exit(x) else exit(y);
end;
procedure main1;
var
i,j:longint;
begin
for i:=2 to n do
begin
for j:=2 to (n shl 1)-2 do
begin
if (a[i,j]='-') and ((a[i-1,j-1]<>'#') and (a[i-1,j]<>'#') and (a[i-1,j+1]<>'#')) then
begin
f[i,j]:=min(f[i-1,j-1],min(f[i-1,j],f[i-1,j+1]))+1;
if (f[i,j]>ans) and (odd(j-i+1)) then ans:=f[i,j];
end;
end;
end;
end;
procedure main2;
var
i,j:longint;
begin
for i:=1 to n-1 do
begin
for j:=2 to (n shl 1)-2 do
begin
if (a[i,j]='-') and ((a[i+1,j-1]<>'#') and (a[i+1,j]<>'#') and (a[i+1,j+1]<>'#')) then
begin
ff[i,j]:=min(ff[i+1,j-1],min(ff[i+1,j],ff[i+1,j+1]))+1;
if (ff[i,j]>ans) and (not odd(j-i+1)) then ans:=ff[i,j];
end;
end;
end;
end;
begin
assign(input,'VJ1063.in'); reset(input);
assign(output,'VJ1063.out'); rewrite(output);
init;
main1;
main2;
writeln(sqr(ans));
close(input); close(output);
end.