zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    POJ 1328 Radar Installation
    POJ 1700 Crossing River
    POJ 1700 Crossing River
    poj 3253 Fence Repair (贪心,优先队列)
    poj 3253 Fence Repair (贪心,优先队列)
    poj 3069 Saruman's Army(贪心)
    poj 3069 Saruman's Army(贪心)
    Redis 笔记与总结2 String 类型和 Hash 类型
    数据分析方法有哪些_数据分析方法
    数据分析方法有哪些_数据分析方法
  • 原文地址:https://www.cnblogs.com/ay27/p/2713343.html
Copyright © 2011-2022 走看看