您的位置:首页 > 其它

zju1093 monkey and banana 猴子和香蕉

2013-11-06 19:27 260 查看
有一班科学家正在设计一个测试猴子IQ的试验。他们把一只“banana”吊在天花板,而且同时给猴子一些箱子。如果猴子聪明的话,它们会把箱子一个个叠起来做成一个塔子来取得食物。科学家有n种箱子,而且每一种箱子都有好多个。第 i 种箱子有三维(xi,yi,zi)。箱子可以用它的任意一面作底面来摆放,也就是它的三维之中可以任选两条来做它的底面长和宽。科学家想确定箱子叠到最高的时候是可以到达天花板的。现在问题是,要叠起一个塔子,上下摆放的两个箱子,在上的箱子的底面长宽必须严格小于在下的箱子的底面长宽,留下些地方让猴子落脚来爬上去。也就是说,底面面积相等的箱子不能叠放。现在你的任务是利用所给定的箱子,决定塔子最高能达到的高度输入方式:

输入数据有多组测试数据。

每一组测试数据的第一行是一个整数n,表示不同三维的箱子的总数。n最大为30。

以下的n行每一行有三个正整数,表示该箱子的三维xi,yi和zi。

当n=0的时候输入结束。输出方式:
对应每组测试数据,输出一行包括数据组号case(从1开始)和塔子最高高度height,并按照一下格式: "Case case: maximum height = height" 

每个箱子有六个面,只有三种面,所以每个箱子我们可分成3中箱子,然后将箱子的横坐标排序即可。类似于dp求最长子序列。

code:

 

var
x,y,f,z:array[0..180] of longint;
n,ans,zzb:longint;

procedure qsort(L,r:Longint);
var i,j,m,t,mm:Longint;
begin
i:=l; j:=r; m:=x[(i+j) div 2]; mm:=y[(i+j) div 2];
repeat
while (x[i]>m) or ((x[i]=m) and (y[i]>mm)) do inc(i);
while (x[j]<m) or ((x[j]=m) and (y[j]<mm)) do dec(j);
if i<=j then
begin
t:=x[i]; x[i]:=x[j]; x[j]:=t;
t:=y[i]; y[i]:=y[j]; y[j]:=t;
t:=z[i]; z[i]:=z[j]; z[j]:=t;
inc(i); dec(j);
end;
until i>j;
if l<j then qsort(l,j);
if i<r then qsort(i,r);
end;

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

procedure init;
var i,j,k,a,b,c:longint;
begin
readln(n); zzb:=0;
while n<>0 do
begin
inc(zzb);
fillchar(f,sizeof(f),0);  ans:=0;
for i:=1 to n do
begin
readln(a,b,c);
x[i*6-5]:=b; y[i*6-5]:=a; z[i*6-5]:=c;
x[i*6-4]:=c; y[i*6-4]:=b; z[i*6-4]:=a;
x[i*6-3]:=a; y[i*6-3]:=c; z[i*6-3]:=b;
x[i*6-2]:=a; y[i*6-2]:=b; z[i*6-2]:=c;
x[i*6-1]:=b; y[i*6-1]:=c; z[i*6-1]:=a;
x[i*6]:=c;   y[i*6]:=a;   z[i*6]:=b;
end;
n:=6*n;
qsort(1,n);
f[1]:=z[1];
for i:=2 to n do
begin
for j:=1 to i-1 do
if ((x[i]<x[j]) and (y[i]<y[j])) then
f[i]:=max(f[i],f[j]);
f[i]:=f[i]+z[i];
ans:=max(ans,f[i]);
end;
writeln('Case ',zzb,': maximum height = ',ans);
readln(n);
end;
end;
begin
init;
end.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: