• 【USACO 1.4.1】铺放矩形块


    【描述】

    给定4个矩形块,找出一个最小的封闭矩形将这4个矩形块放入,但不得相互重叠。所谓最小矩形指该矩形面积最小。
     
     
     
     
     
     
     

    所有4个矩形块的边都与封闭矩形的边相平行,图1示出了铺放4个矩形块的6种方案。这6种方案是仅可能的基本铺放方案。因为其它方案能由基本方案通过旋转和镜像反射得到。

    可能存在满足条件且有着同样面积的各种不同的封闭矩形,你应该输出所有这些封闭矩形的边长。

    (分类注解:这里的分类依据可以视为是不同的面积计算公式。)

    【格式】

    INPUT FORMAT:
    (file packrec.in)
    共有4行。每一行用两个正整数来表示一个给定的矩形块的两个边长。矩形块的每条边的边长范围最小是1,最大是50。
    OUTPUT FORMAT:
    (file packrec.out)
    总行数为解的总数加1。第一行是一个整数,代表封闭矩形的最小面积(子任务A)。接下来的每一行都表示一个解,由数P和数Q来表示,并且P≤Q(子任务B)。这些行必须根据P的大小按升序排列,P小的行在前,大的在后。且所有行都应是不同的。

    【分析】

    对于这道题,我只能说诡异......

    实际上,如果把题目中的4个矩形变成n个矩形,这会是一道相当难的题目,但是在题目中给定了限制条件之后,求解变得可能了。

    怎么说呢?情况数很多,但是仔细思考后并不是特别难,只是要注意特殊情况。

    附参考:http://hi.baidu.com/nash635/item/6619502e7b9020f851fd8701

    代码有点丑了......

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cmath>
      4 #include <cstring>
      5 #include <algorithm>
      6 const int maxn=15;
      7 using namespace std;
      8 struct matrix
      9 {
     10        int w;
     11        int h;
     12 }data[maxn];
     13 struct Ans
     14 {
     15        int w;
     16        int h;
     17        int s;
     18        bool operator <(const Ans&b) const
     19        {
     20             if (s==b.s) return w<b.w;
     21             return s<b.s;
     22        }
     23 }ans[60000];
     24 int point=0;
     25 void check(matrix a,matrix b,matrix c,matrix d);
     26 int main()
     27 {
     28     int i,a,b,c,d;
     29     int vis[15];
     30     //文件操作 
     31     freopen("packrec.in","r",stdin);
     32     freopen("packrec.out","w",stdout);
     33     for (i=1;i<=4;i++)
     34     {
     35         scanf("%d%d",&data[i].w,&data[i].h);
     36         data[i+4].w=data[i].h;
     37         data[i+4].h=data[i].w;//不同的擺放狀態也應該記作不同的矩形 
     38     }
     39     
     40     for (a=1;a<=8;a++)
     41     for (b=1;b<=8;b++)
     42     {
     43         if (a==b) continue;
     44         for (c=1;c<=8;c++)
     45         {
     46             if (a==c || b==c) continue;
     47             for (d=1;d<=8;d++)
     48             {
     49                 if (a==d || b==d || c==d) continue;
     50                 memset(vis,0,sizeof(vis));
     51                 vis[a]++;vis[b]++;vis[c]++;vis[d]++;
     52                 if (vis[1]+vis[5]>1) continue;
     53                 if (vis[2]+vis[6]>1) continue;
     54                 if (vis[3]+vis[7]>1) continue;
     55                 if (vis[4]+vis[8]>1) continue;
     56                 check(data[a],data[b],data[c],data[d]);
     57             }
     58         }
     59     }
     60 
     61     sort(ans,ans+point);
     62     printf("%d
    ",ans[0].s);
     63     for (i=0;i<point;i++)
     64     {
     65         if (i!=0 && ans[i].s!=ans[i-1].s) break;
     66         if (i!=0 && ans[i].w==ans[i-1].w) continue;
     67         printf("%d %d
    ",ans[i].w,ans[i].h);
     68     }
     69     return 0;
     70 }
     71 void check(matrix a,matrix b,matrix c,matrix d)
     72 {
     73      //枚舉
     74      ans[point].w=a.w+b.w+c.w+d.w;ans[point].h=max(a.h,max(b.h,max(c.h,d.h))); 
     75      ans[point].s=ans[point].w*ans[point].h;
     76      if (ans[point].w>ans[point].h) swap(ans[point].w,ans[point].h);
     77      point++;
     78      ans[point].w=max(a.w+b.w+c.w,d.w);ans[point].h=max(a.h,max(b.h,c.h))+d.h;
     79      ans[point].s=ans[point].w*ans[point].h;
     80      if (ans[point].w>ans[point].h) swap(ans[point].w,ans[point].h);
     81      point++;
     82      ans[point].w=max(a.w+b.w,c.w)+d.w;
     83      ans[point].h=max(a.h+c.h,max(b.h+c.h,d.h));
     84      ans[point].s=ans[point].w*ans[point].h;
     85      if (ans[point].w>ans[point].h) swap(ans[point].w,ans[point].h);
     86      point++;
     87      ans[point].w=a.w+b.w+max(c.w,d.w);
     88      ans[point].h=max(a.h,max(c.h+d.h,b.h));
     89      ans[point].s=ans[point].w*ans[point].h;
     90      if (ans[point].w>ans[point].h) swap(ans[point].w,ans[point].h);
     91      point++;
     92      ans[point].h=max(a.h+c.h,b.h+d.h);
     93      if (c.h==d.h) ans[point].w=max(a.w+b.w,c.w+d.w);
     94      if (c.h>=b.h+d.h) ans[point].w=max(a.w,max(c.w+b.w,c.w+d.w));
     95      if (c.h>d.h && c.h<b.h+d.h) ans[point].w=max(a.w+b.w,max(b.w+c.w,c.w+d.w));
     96      if (d.h>c.h && d.h<a.h+c.h) ans[point].w=max(a.w+b.w,max(a.w+d.w,c.w+d.w));
     97      if (d.h>=a.h+c.h) ans[point].w=max(b.w,max(a.w+d.w,c.w+d.w));
     98      ans[point].s=ans[point].w*ans[point].h;
     99      if (ans[point].w>ans[point].h) swap(ans[point].w,ans[point].h);
    100      point++;
    101 }
  • 相关阅读:
    Python
    算法的时间复杂度和空间复杂度-总结
    列表自动滚动
    React 结合ant-mobile 省市区级联
    5G从小就梦想着自己要迎娶:高速率、低时延、大容量三个老婆
    一文读懂GaussDB(for Mongo)的计算存储分离架构
    cpu占用过高排查
    我是如何从零开始自学转行IT并进入世界500强实现薪资翻倍?
    Linux重定向用法详解
    说出来也许你不信,我被 Linux 终端嘲笑了……
  • 原文地址:https://www.cnblogs.com/hoskey/p/3784646.html
Copyright © 2020-2023  润新知