Usaco 1.4.1 铺放矩形块(Packing Rectangles)

本文详细讲解了Usaco编程竞赛中1.4.1题目的解题思路,主要涉及如何高效地处理矩形块的排列与计算。通过实例解析,帮助读者理解矩阵在该问题中的应用。

题目:

 铺放矩形块

来源:

 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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值