题目: | 铺放矩形块 | |
来源: | Usaco1.4.1 | |
题目大意: | 已知4个矩形的长宽,求其各自不覆盖所组成的最小矩形(已给出六个模板),输出最小矩形面 积和各个解(即该矩形长宽,按升序排,且第一个值小于等于该行第二个) | |
数据范围: | 矩形块的每条边的边长范围最小是1,最大是50 | |
样例: |
1 2 2 3 3 4 4 5 |
40 4 10 5 8 |
做题思路: | 仅有这几种方法,仅有4个矩形块,所以枚举在每个模板上每个位置是哪个矩形块就好,对每个 模板分别处理代码啰嗦,所以同时处理所有模板,由于每个边可以当长或宽,所以枚举边在最 外层循环。最后对长宽进行处理,打擂台,小的记录,等于的标号。 | |
知识点: | 枚举、模拟、矩形面积计算、位运算 |
{
ID:Dount Nameless
TASK:packrec
LANG:PASCAL
}
var
i,j,s,s0,s1,s2,s3,s4,x1,x2,x3,x4,y1,y2,y3,y4:longint;
a,b,position:array[1..4]of longint;
l:array[1..5,1..2]of longint;
change:array[1..4] of boolean;
matrix:array[1..200,1..200]of boolean;
procedure deal(n:longint);{<用二进制模拟边的横竖情况>}
begin
inc(position[n]);
change[n]:=true;
if (position[n]=2)and(n<4) then deal(n+1);
position[n]:=position[n] mod 2
end;
procedure swap(var a,b:longint);
var
temp:longint;
begin
temp:=a; a:=b; b:=temp
end;
function big(a,b:longint):longint;
begin
If a>b then exit(a);
exit(b)
end;
begin
assign(input,'packrec.in'); reset(input);
assign(output,'packrec.out'); rewrite(output);
fori:=1 to 4 do read(a[i],b[i]);
s0:=maxint;
fori:=0 to 15 do{<枚举每条边的横竖放置 共2^4种>}
begin
fillchar(change,sizeof(change),0);
deal(1);
for j:=1 to 4 do If change[j] then swap(a[j],b[j]);{<如果改变,则交换长宽>}
for s1:=1 to 4 do
for s2:=1 to 4 do
if s2<>s1 then
for s3:=1 to 4 do
if(s3<>s1)and(s3<>s2)then
begin
s4:=10-s1-s2-s3;{<知三求一>}
x1:=a[s1]; y1:=b[s1];{<模板内的四个位置>}
x2:=a[s2]; y2:=b[s2];
x3:=a[s3]; y3:=b[s3];
x4:=a[s4]; y4:=b[s4];
l[1,1]:=x1+x2+x3+x4; l[1,2]:=big(y1,big(y2,big(y3,y4)));{<求模板的长宽>}
l[2,1]:=big(x1,x2+x3+x4); l[2,2]:=y1+big(y2,big(y3,y4));
l[3,1]:=big(x1+x2,x3)+x4; l[3,2]:=big(y4,big(y1,y2)+y3);
l[4,1]:=big(x2,x3)+x1+x4; l[4,2]:=big(y1,big(y2+y3,y4));{<4、5同解>}
l[5,1]:=big(x1+x2,big(x3,x4)); l[5,2]:=big(y1+y3,y2+y4);{<第六个模板>}
if y1<y2 thenl[5,1]:=big(l[5,1],x2+x3);{<有横着放的>}
if y1>y2 thenl[5,1]:=big(l[5,1],x1+x4);
if y1+y3>y2 thenl[5,1]:=big(l[5,1],x3+x4);
for j:=1 to 5 do
begin
if l[j,1]>l[j,2] thenswap(l[j,1],l[j,2]);{<确保p<=q>}
s:=l[j,1]*l[j,2];
if s<s0 then{<打擂台>}
begin
fillchar(matrix,sizeof(matrix),0);
s0:=s
end;
if s=s0 thenmatrix[l[j,1],l[j,2]]:=true{<标记相同解>}
end
end
end;
writeln(s0);
fori:=1 to 200 do
for j:=i to 200 do
if matrix[i,j] then writeln(i,' ',j);{<省去排序,直接判读>}
close(input); close(output)
end.
题目来源:http://ace.delos.com/usacoprob2?a=RexmW8CclSt&S=packrec