• USACOPacking Rectangles


    http://ace.delos.com/usacoprob2?a=GOVL6gcgbQL&S=packrec

    嗯,一道无比恶心的题。。。。

    无标题

    观察好这几个图形,基本上就要靠这几个图形做题了。这题恶心的地方除了这几个图形,还有就是暴搜的方法,要全排列生成4个矩形的排列,然后才能按照上面几个图形来划分cases。注意了,第四个和第五个图形是一样的,只不过把中间的一列和左边的一列交换了位置。还有一个恶心的地方就是最后一个图形了,这里是这道题无比恶心的源泉啊(+﹏+)~狂晕。。。。

    至于第六个图形,主要是讨论下面两个矩阵对整个大矩阵的宽的影响。

    具体的用笔画一下吧,不再累赘了。。。。

    #include <iostream>
    #include <string.h>
    #include <cstdio>
    #include <algorithm>
    using namespace std;
    
    struct node{
        int w,h;
        friend bool operator < (node a,node b)
        {
            return a.w<b.w;
        }
    }r[5];
    
    int per[5]={0,1,2,3,4};
    int sum=0,square=99999999;
    node f[1000];
    
    void swap(node &a)
    {
        int x;
        x=a.w; a.w=a.h; a.h=x;
    }
    
    int max2(int xx,int yy)
    {
        return (xx>yy)?xx:yy;
    }
    
    int max3(int xx,int yy,int zz)
    {
        return (max2(max2(xx,yy),zz));
    }
    
    int max4(int xx,int yy,int zz,int aa)
    {
        return (max2(max2(xx,yy),max2(zz,aa)));
    }
    
    void check(int ww,int hh)
    {
        if (ww*hh<square)
        {
            square=ww*hh;
            sum=0;
            f[++sum].w=min(ww,hh); f[sum].h=max(ww,hh);
        }
        else if (ww*hh==square)
        {
            f[++sum].w=min(ww,hh);
            f[sum].h=max(ww,hh);
        }
    }
    
    void case1(node a,node b,node c,node d)        //图形1
    {
        int ww=a.w+b.w+c.w+d.w;
        int hh=max4(a.h,b.h,c.h,d.h);
        check(ww,hh);
    }
    
    void case2(node a,node b,node c,node d)          //图形2
    {
        int ww=max2(a.w+b.w+c.w,d.w);
        int hh=max3(a.h,b.h,c.h)+d.h;
        check(ww,hh);
    }
    
    void case3(node a,node b,node c,node d)       //图形3
    {
        int ww=max2(a.w+b.w,c.w)+d.w;
        int hh=max2(max2(a.h,b.h)+c.h,d.h);
        check(ww,hh);
    }
    
    void case4(node a,node b,node c,node d)            //图形4和图形5
    {
        int ww=a.w+max2(b.w,c.w)+d.w;
        int hh=max3(a.h,b.h+c.h,d.h);
        check(ww,hh);
    }
    
    void case5(node a,node b,node c,node d)      //无比恶心的图形6,注意好大于小于等于,注意.w和.h了。。。
    {
        int ww=0;
        if (c.h>=b.h+d.h)
            ww=max3(a.w,b.w+c.w,c.w+d.w);
        else if (c.h>d.h && c.h<b.h+d.h)
            ww=max3(a.w+b.w,c.w+b.w,c.w+d.w);
        else if (c.h<d.h && a.h+c.h>d.h)
            ww=max3(a.w+b.w,a.w+d.w,c.w+d.w);
        else if (d.h>=a.h+c.h)
            ww=max3(b.w,a.w+d.w,c.w+d.w);
        else if (c.h==d.h)
            ww=max2(a.w+b.w,c.w+d.w);
        int hh=max2(a.h+c.h,b.h+d.h);
        check(ww,hh);
    }
    
    void work(node a,node b,node c,node d)
    {
        case1(a,b,c,d);
        case2(a,b,c,d);
        case3(a,b,c,d);
        case4(a,b,c,d);
        case5(a,b,c,d);
    }
    
    int main()
    {
        freopen("packrec.in","r",stdin);
        freopen("packrec.out","w",stdout);
        for (int i=1;i<=4;i++)
            cin>>r[i].w>>r[i].h;
        //这里要用do..while,用while的话,第一种原始排列就没有了
        do       //每一个swap都是矩阵的旋转
        {
            for (int i=1;i<=2;i++)
            {
                swap(r[1]);
                for (int j=1;j<=2;j++)
                {
                    swap(r[2]);
                    for (int k=1;k<=2;k++)
                    {
                        swap(r[3]);
                        for (int l=1;l<=2;l++)
                        {
                            swap(r[4]);
                            work(r[per[1]],r[per[2]],r[per[3]],r[per[4]]);
                        }
                    }
                }
            }
        }while (next_permutation(per+1,per+5));     //全排列生成法,要感谢STL了
        cout<<square<<endl;
        sort(f+1,f+sum+1);
        for (int i=1;i<=sum;i++)
        {
            if (f[i].w==f[i-1].w && f[i].h==f[i-1].h) continue;
            cout<<f[i].w<<" "<<f[i].h<<endl;
        }
        return 0;
    }

    借用了zephyrQ的思想:

    http://www.cnblogs.com/kissfinger/archive/2011/03/08/1977720.html

  • 相关阅读:
    Java动态代理(三)——模拟AOP实现
    Java动态代理(二)CGLIB动态代理应用
    Java动态代理(一)动态类Proxy的使用
    CGLIB实现动态代理
    初识Java微信公众号开发
    spring+ibatis事务管理配置
    什么是事务的传播特性
    Spring事务配置的五种方式
    Java语言基础(五) Java原始数据类型的分类以及数据范围
    Java语言基础(四) String和StringBuffer的区别
  • 原文地址:https://www.cnblogs.com/ay27/p/2713343.html
Copyright © 2020-2023  润新知