Section 1.4 Packing Rectangles

此题是IOI的水平竟放在Section 1 里不可思议

鉴于此题过于难 本人就百度了一下

结果发现N多人代码完全相同 本人也就不好意思说啥了

于是本人就找了一个PASCAL 的代码来分析

先把图标上号

pack

本人是用f[1..4,1..2]来存的 1..4表示图形 1..2记录横竖

有人会问为啥不用记录来存呢?到后面就清楚了

然后枚举编号以及横竖 我是用s数组和d数组做的

通过枚举,又可以的到2个数组 x, y  x记录横着的 y记录竖着的

然后就是公式了 用m 记录长 n记录宽 则有

方案1

     m := x[1]+x[2]+x[3]+x[4];
     n := max(y[1], y[2], y[3], y[4]);
方案2
     m := max(x[1]+x[2]+x[3], x[4], 0, 0);
     n := y[4]+max(y[1], y[2], y[3], 0);

方案3
     m := max(x[1]+x[2], x[3], 0, 0) + x[4];
     n := max(y[3]+y[1], y[3]+y[2], y[4], 0);

方案4和5
     m := x[1] + x[2] + max(x[3], x[4], 0, 0);
     n := max(y[1], y[2], y[3]+y[4], 0);
方案6就是两个两个的摆法 因而有多种情况 具体的有这么一张图 本人百度到的

图片1 wps_clip_image-16037


     n := max(y[1]+y[3], y[2]+y[4], 0, 0);
     if y[3] >= y[2]+y[4] then
      m := max(x[1], x[2]+x[3], x[3]+x[4], 0);
     if (y[3] > y[4]) and (y[3]       m := max(x[1]+x[2], x[3]+x[4], x[3]+x[2], 0);
     if (y[3] < y[4]) and (y[4]       m := max(x[3]+x[4],x[1]+x[2],x[1]+x[4],0);
     if y[4]>=y[1]+y[3] then
      m := max(x[2], x[1]+x[4], x[3]+x[4], 0);
     if y[3]=y[4] then
      m := max(x[1]+x[2], x[3]+x[4], 0, 0);

然后就记录下就可以啦

前4种方案应该是很容易看懂的 最后一种要思考一下 本人是看懂了

当然这全不是自己想的 感谢百度和前辈们 最后发代码 庆祝一下

{
ID: yaoyuan4
PROG: packrec
LANG: PASCAL
}
Program packrec;
const
  inf = 'packrec.in'; outf = 'packrec.out';
var
  f : array[1..4, 1..2] of longint;
  total : longint;
  ans : array[1..20, 1..2] of longint;
Function maxi(a, b : longint) : longint;
  begin
   if a > b then exit(a) else exit(b);
  end;
Function max(a, b, c, d : longint) : longint;
  begin
   exit(maxi(maxi(a, b), maxi(c, d)));
  end;
Procedure swap(var a, b : longint);
  var
   t : longint;
  begin
   t := a;
   a := b;
   b := t;
  end;
Procedure news(a, b : longint);
  var
   i : longint;
  begin
   if a > b then swap(a, b);
   if a * b < ans[1,1] * ans[1,2] then
    begin
     total := 1;
     ans[1,1] := a;
     ans[1,2] := b;
    end;
   if a * b = ans[1,1] * ans[1,2] then
    begin
     for i := 1 to total do
      if (a = ans[i,1]) and (b = ans[i,2]) then
       exit;
     inc(total);
     ans[total,1] := a;
     ans[total,2] := b;
    end;
  end;
Procedure init;
  var
   i, j : longint;
  begin
   assign(input, inf); reset(input);
   for i := 1 to 4 do
    readln(f[i, 1], f[i, 2]);
   close(input);
   total := 1;
   ans[1,1] := 100;
   ans[1,2] := 100;
  end;
Procedure work;
  var
   s1, s2, s3, s4, d1, d2, d3, d4, x1, x2, x3, x4, y1, y2, y3, y4 : longint;
   s, d, x, y : array[1..4] of longint;
   i, j, m, n : longint;
   flag : boolean;
  begin
   for s1 := 1 to 4 do
   for s2 := 1 to 4 do
   for s3 := 1 to 4 do
   for s4 := 1 to 4 do
    if [s1, s2, s3, s4] = [1..4] then
     for d1 := 1 to 2 do
     for d2 := 1 to 2 do
     for d3 := 1 to 2 do
     for d4 := 1 to 2 do
      begin
       s[1] := s1; s[2] := s2; s[3] := s3; s[4] := s4;
       d[1] := d1; d[2] := d2; d[3] := d3; d[4] := d4;
       for i := 1 to 4 do
        begin
         x[i] := f[s[i], d[i]];
         y[i] := f[s[i], 3 - d[i]];
        end;
       m := x[1]+x[2]+x[3]+x[4];
       n := max(y[1], y[2], y[3], y[4]);
       news(m, n);
       m := max(x[1]+x[2]+x[3], x[4], 0, 0);
       n := y[4]+max(y[1], y[2], y[3], 0);
       news(m, n);
       m := max(x[1]+x[2], x[3], 0, 0) + x[4];
       n := max(y[3]+y[1], y[3]+y[2], y[4], 0);
       news(m, n);
       m := x[1] + x[2] + max(x[3], x[4], 0, 0);
       n := max(y[1], y[2], y[3]+y[4], 0);
       news(m, n);
       n := max(y[1]+y[3], y[2]+y[4], 0, 0);
       if y[3] >= y[2]+y[4] then
        m := max(x[1], x[2]+x[3], x[3]+x[4], 0);
       if (y[3] > y[4]) and (y[3]         m := max(x[1]+x[2], x[3]+x[4], x[3]+x[2], 0);
       if (y[3] < y[4]) and (y[4]         m := max(x[3]+x[4],x[1]+x[2],x[1]+x[4],0);
       if y[4]>=y[1]+y[3] then
        m := max(x[2], x[1]+x[4], x[3]+x[4], 0);
       if y[3]=y[4] then
        m := max(x[1]+x[2], x[3]+x[4], 0, 0);
       news(m, n);
      end;
   j := total;
   repeat
    flag := true;
    for i := 1 to j - 1 do
     if ans[i,1] > ans[i+1,1] then
      begin
       swap(ans[i,1], ans[i+1,1]);
       swap(ans[i,2], ans[i+1,2]);
       flag := false;
      end;
    dec(j);
   until flag;
  end;
Procedure print;
  var
   i : longint;
  begin
   assign(output, outf); rewrite(output);
   writeln(ans[1,1] * ans[1,2]);
   for i := 1 to total do
    writeln(ans[i,1],' ',ans[i,2]);
   close(output);
  end;
begin
  init;
  work;
  print;
end.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值