[USACO 1.4.1] Packing Rectangles

[題目描述]

Packing Rectangles

鋪放矩形塊

IOI 95


給定4個矩形塊,找出一個最小的封閉矩形將這4個矩形塊放入,但不得相互重疊。所謂最小矩形指該矩形面積最小。
所有4個矩形塊的邊都與封閉矩形的邊相平行,圖1示出了鋪放4個矩形塊的6種方案。這6種方案僅只是可能的基本鋪放方案。因爲其它方案能由基本方案通過旋轉和鏡像反射得到。
可能存在滿足條件且有着同樣面積的各種不同的封閉矩形,你應該輸出所有這些封閉矩形的邊長。

PROGRAM NAME: packrec

INPUT FORMAT

共有4行。每一行用兩個正整數來表示一個給定的矩形塊的兩個邊長。矩形塊的每條邊的邊長範圍最小是1,最大是50

SAMPLE INPUT (file packrec.in)

1 2
2 3
3 4
4 5

OUTPUT FORMAT

總行數爲解的總數加1。第一行是一個整數,代表封閉矩形的最小面積(子任務A)。接下來的每一行都表示一個解,由數P和數Q來表示,並且P≤Q(子任務B)。這些行必須根據P的大小按升序排列,P小的行在前,大的在後。且所有行都應是不同的。

SAMPLE OUTPUT (file packrec.out)

40
4 10
5 8


[解題思路]

IOI 的神級題啊、 Orz...

看數據範圍應該是搜,但具體方法想了好久都沒有思路。枚舉長寬吧,檢驗複雜度過高,並且不好實現,要用棧記錄可以放的點;迭代枚舉最小面積吧,同樣還是要枚舉長寬......

絕望之中百度了下,發現神犇的Bo,觀摩入口在這裏

其實就是題目中給定的幾種基本情況(看題的時候根本沒注意... = =、),枚舉4個矩形的排列順序,再枚舉每一種擺放方法,記錄最優解,排序輸出即可。

130+行的代碼,觀Bo之後,自己重新手枚一遍的結果,一僞代碼照着敲的...


[Code]

{
ID: zane2951
PROG: packrec
LANG: PASCAL
}

program packrec;
var
   x,y,q,l,h:array[0..5] of longint;
   xx,yy:array[0..1111] of longint;
   f:array[0..201,0..201] of boolean;
   ans,top,i,i1,i2,i3,i4:longint;

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

//-----------up------------
procedure up(hh,ll:longint);
var
   tmp:longint;

begin
   if ll<hh then begin tmp:=ll; ll:=hh; hh:=tmp; end;
   if hh*ll<=ans then
      if hh*ll<ans then
         begin
            ans:=hh*ll;
            top:=1;
            xx[top]:=hh;
            yy[top]:=ll;
            f[hh,ll]:=true;
            f[ll,hh]:=true;
         end
         else
            if not f[hh,ll] then
               begin
                  inc(top);
                  xx[top]:=hh;
                  yy[top]:=ll;
                  f[hh,ll]:=true;
                  f[ll,hh]:=true;
               end;
end;

//---------check-----------
procedure check;
var
   hh,ll:longint;

begin
   hh:=max(h[1],max(h[2],max(h[3],h[4])));
   ll:=l[1]+l[2]+l[3]+l[4];
   up(hh,ll);

   hh:=max(h[1],max(h[2],h[3]))+h[4];
   ll:=max(l[4],l[1]+l[2]+l[3]);
   up(hh,ll);

   hh:=max(h[3],max(h[1]+h[4],h[2]+h[4]));
   ll:=max(l[3]+l[4],l[1]+l[2]+l[3]);
   up(hh,ll);

   hh:=max(h[1],max(h[4],h[2]+h[3]));
   ll:=max(l[1]+l[2]+l[4],l[1]+l[4]+l[3]);
   up(hh,ll);

   hh:=max(h[1]+h[3],h[2]+h[4]);
   if h[3]>=h[2]+h[4] then ll:=max(l[1],l[3]+max(l[2],l[4]))
      else
         if (h[3]>h[4]) and (h[3]<h[2]+h[4]) then ll:=max(l[1]+l[2],max(l[2]+l[3],l[3]+l[4]))
         else
            if (h[4]>h[3]) and (h[4]<h[1]+h[3]) then ll:=max(l[1]+l[2],max(l[1]+l[4],l[3]+l[4]))
            else
               if h[4]>=h[1]+h[3] then ll:=max(l[2],max(l[1]+l[4],l[3]+l[4]))
                  else ll:=max(l[1]+l[2],l[3]+l[4]);
   up(hh,ll);
end;

//----------run------------
procedure run(dp:longint);
begin
   if dp>4 then
      begin
         check;
         exit;
      end;
   l[dp]:=x[q[dp]]; h[dp]:=y[q[dp]]; run(dp+1);
   l[dp]:=y[q[dp]]; h[dp]:=x[q[dp]]; run(dp+1);
end;

//-----------qs------------
procedure qs(s,t:longint);
var
   i,j,ce,tmp:longint;

begin
   i:=s; j:=t; ce:=xx[(i+j)>>1];
   repeat
      while xx[i]<ce do inc(i);
      while xx[j]>ce do dec(j);
      if i<=j then
         begin
            tmp:=xx[i]; xx[i]:=xx[j]; xx[j]:=tmp;
            tmp:=yy[i]; yy[i]:=yy[j]; yy[j]:=tmp;
            inc(i); dec(j);
         end;
   until i>j;
   if i<t then qs(i,t); if s<j then qs(s,j);
end;

//----------main-----------
begin
   assign(input,'packrec.in'); reset(input);
   assign(output,'packrec.out'); rewrite(output);
   for i:=1 to 4 do readln(x[i],y[i]);
   ans:=maxlongint;
   for i1:=1 to 4 do
      for i2:=1 to 4 do
         for i3:=1 to 4 do
            for i4:=1 to 4 do
               if (i1<>i2) and (i1<>i3) and (i1<>i4) and
                  (i2<>i3) and (i2<>i4) and (i3<>i4) then
                     begin
                        q[1]:=i1; q[2]:=i2;
                        q[3]:=i3; q[4]:=i4;
                        run(1);
                     end;
   qs(1,top);
   writeln(ans);
   for i:=1 to top do writeln(xx[i],'':1,yy[i]);
   close(input); close(output);
end.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章