usaco 1.4 Packing Rectangles(枚举模拟 含结构体排序)and poj 1169

题意是给你四个矩形,按题目给的六种排法,找出能容纳的下四个矩形的最小矩形面积,并将所求的最小矩形边 按小边 从小到大的顺序输出。


看到这题完全没有思路,网上看大神们的解析,有说到用深搜,但是不知道这题怎么用深搜,大概是自己没有理解 深搜 的用法。

于是选用了令一种思路,枚举。

因为题目中只说了六种情况,所以将他们全表示出来,加上四个矩形的位置及长宽变化,一一枚举。

最后对答案进行排序,即可。


以下截图来自百度文库:http://wenku.baidu.com/view/3cae8f14866fb84ae45c8ddb.html

图一:


图二:


图三:


图四、五:


图六:



usaco ac代码:

/*
ID: who jay
LANG: C++
TASK: packrec
*/
#include <stdio.h>
#include<algorithm>
using namespace std;

int total,MIN=32767,a[5][3],a1,a2,a3,a4,b1,b2,b3,b4;

struct Ans
{
    int x;
    int y;
} ans[100];

int cmp(const void *va,const void *vb)
{
    Ans *a,*b;
    a=(Ans*)va;
    b=(Ans*)vb;
    if(a->x > b->x)
        return 1;
    if(a->x < b->x)
        return -1;
    return 0;
}

void smin(int x,int y)
{
    if(x*y>MIN)
        return;
    if(x*y<MIN)
    {
        MIN=x*y;
        total=0;
    }
    if(x>y)
        swap(x,y);
    for(int i=1; i<=total; i++)
        if(x==ans[i].x&&y==ans[i].y)
            return;
    total++;
    ans[total].x=x;
    ans[total].y=y;
}
void scase()
{
    int wid1=a[a1][b1],wid2=a[a2][b2],wid3=a[a3][b3],wid4=a[a4][b4],len1=a[a1][3-b1],len2=a[a2][3-b2],len3=a[a3][3-b3],len4=a[a4][3-b4],len,wid;

    len=len1+len2+len3+len4;//图一
    wid=max(max(max(wid1,wid2),wid3),wid4);
    smin(len,wid);

    len=max(len1+len2+len3,len4);//图二
    wid=max(max(wid1,wid2),wid3)+wid4;
    smin(len,wid);

    len=max(len1+len2,len3)+len4;//图三
    wid=max(max(wid1,wid2)+wid3,wid4);
    smin(len,wid);

    len=len1+len2+max(len3,len4);//图四、五
    wid=max(max(wid1,wid2),wid3+wid4);
    smin(len,wid);

    len=max(max(len1+len4,len2+len3),len1+len3);
    wid=max(max(wid1+wid2,wid3+wid4),wid2+wid4);
    smin(len,wid);//图六
}
void change()
{
    for(a1=1; a1<5; a1++)
        for(a2=1; a2<5; a2++)
            if(a1!=a2)
                for(a3=1; a3<5; a3++)
                    if(a3!=a2&&a3!=a1)
                    {
                        a4=10-a1-a2-a3;//枚举4种摆放位置 即a1,a2,a3,a4 互相交换
                        for(b1=1; b1<3; b1++)
                            for(b2=1; b2<3; b2++)
                                for(b3=1; b3<3; b3++)
                                    for(b4=1; b4<3; b4++) //枚举矩形的摆放形式(横或竖)
                                        scase();
                    }
}
int main()
{
    freopen("packrec.in","r",stdin);
    freopen("packrec.out","w",stdout);
    int i;
    for(i=1; i<5; i++)
        scanf("%d %d",&a[i][1],&a[i][2]);

    change();

    qsort(ans,total+1,sizeof(Ans),cmp);
    printf("%d\n",MIN);
    for(i=1; i<=total; i++)
        printf("%d %d\n",ans[i].x,ans[i].y);
    fclose(stdin);
    fclose(stdout);
    return 0;
}

poj 上把相应处理文件的语句去掉就ok了~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值