对USACO1.4.1的看法和总结

  USACO1.4.1题目要求输入四个长方形的长宽,然后进行摆放,求出用一个最小的矩形把四个小矩形放入其中,并且不得重叠。输出满足条件的最小矩形,然后按照这个矩形的长宽进行排序,并且不得重复。

  这道题的关键在于矩阵的摆放,因为摆放可以通过镜像和旋转来得到,所以所有的摆放可以总结成六种方法,六种方法网上有图,那么就要对这六种方法进行分析,分析出满足条件的矩形的长宽,之后就是矩形的长宽互换,依次互换,总共进行16次转换,同时还要进行位置的转换,即为四个矩形相互交换位置,就是有24中交换方法。之后就是对结果的选择和排序。

  在这道题目中遇到的问题有,转换的时候使用递归好?还是用迭代来代替?目前我自己使用的是递归的方法,因为总共次数不多,只有1900+次。所以还在计算机的能力范围内,还有就是依次递归时,所用的方法似乎叫做回溯法,但好像要依次进行回溯,需要两个判断来定义,我用的是一个for循环,和一个if语句来规定两个判断。目前我还不知道有没有更简单的回溯法。还有就是在进行四个矩形互换位置的时候忘记了容器不能对容器自身进行存放,需要再找一个容器先来存放的原则,导致一开始有错误答案。而且对不同的题目也要有针对性的改正,像这道题只要找最大值,那么就不需要对有所的进行排序而是只需要找出最小值即可,然后对最小值进行再查找,找出长宽,进行排序。这样可以简化运算步骤,增大可行性。

  记住特定问题特定分析

下面是我的代码:#include<iostream>
using namespace std;
int a[8][2]= {},z=-1,w=0,h=0,result[2000]= {},result1[2000]= {},result2[2000]= {};
int findmax(int x1=0,int x2=0,int x3=0,int x4=0);
void zhuanhuan1(int);
int main()
{
    int u1,u2,u3,u4,u5,u6,u7,u8;
    for(int n=0; n<4; n++)
    {
        cin>>a[n][0]>>a[n][1];
        a[n+4][0]=a[n][0];
        a[n+4][1]=a[n][1];
    }
    zhuanhuan1(0);
    for(int k=1; k<5; k++)
    {
        for(int n=4; n<8; n++)
        {
            for(int n1=4; n1<8; n1++)
            {
                for(int n2=4; n2<8; n2++)
                {
                    for(int n3=4; n3<8; n3++)
                    {
                        if(n!=n1&&n!=n2&&n!=n3&&n1!=n2&&n1!=n3&&n2!=n3)
                        {
                            u1=a[0][0];
                            u2=a[0][1];
                            a[0][0]=a[n][0];
                            a[0][1]=a[n][1];
                            u3=a[1][0];
                            u4=a[1][1];
                            a[1][0]=a[n1][0];
                            a[1][1]=a[n1][1];
                            u5=a[2][0];
                            u6=a[2][1];
                            a[2][0]=a[n2][0];
                            a[2][1]=a[n2][1];
                            u7=a[3][0];
                            u8=a[3][1];
                            a[3][0]=a[n3][0];
                            a[3][1]=a[n3][1];
                            zhuanhuan1(k);
                            a[0][0]=u1;
                            a[0][1]=u2;
                            a[1][0]=u3;
                            a[1][1]=u4;
                            a[2][0]=u5;
                            a[2][1]=u6;
                            a[3][0]=u7;
                            a[3][1]=u8;
                        }
                    }
                }
            }
        }
    }
    int cc=result[0];
    for(int n=0; n<h; n++)
    {
        if(result[n]<cc)
        {
            cc=result[n];
        }
    }
    cout<<cc<<endl;
    int hh=0,zz=0;
    for(int n=0; n<h; n++)
    {
        if(result[zz]==cc)
        {
            zz++;
        }
        if(result[hh]==cc&&result[zz]!=cc)
        {
            if(result1[hh]>result2[hh])
            {
                result1[zz]=result2[hh];
                result2[zz]=result1[hh];
                zz++;
            }
            else if(result1[hh]<=result2[hh])
            {
                result1[zz]=result1[hh];
                result2[zz]=result2[hh];
                zz++;
            }
        }
        hh++;
    }
    int zzz=1;
    while(zzz!=0)
    {
        zzz=0;
        for(int n=0; n<zz-1; n++)
        {
            if(result1[n]>result1[n+1])
            {
                int aaa=result1[n];
                result1[n]=result1[n+1];
                result1[n+1]=aaa;
                aaa=result2[n];
                result2[n]=result2[n+1];
                result2[n+1]=aaa;
                zzz++;
            }
        }
    }
    for(int n=0; n<zz; n++)
    {
        int uu=0;
        for(int w=0; w<n; w++)
        {
            if(result1[n]==result1[w]&&result2[n]==result2[w])
                uu++;
        }
        if(uu==0)cout<<result1[n]<<" "<<result2[n]<<endl;
    }
for(int n=0;n<h;n++)
{
    if(result[n]==60&&result1[n]==5&&result2[n]==12||result[n]==60&&result2[n]==5&&result1[n]==12)
        cout<<n<<endl;
}
}
int findmax(int x1,int x2,int x3,int x4)
{
    int c=x1;
    if(x2>x1)
    {
        c=x2;
    }
    if(x3>c)
    {
        c=x3;
    }
    if(x4>c)
    {
        c=x4;
    }
    return c;
}
void zhuanhuan1(int k)
{

    if(z<3)
    {
        for(int n=0; n<2; n++)
        {
            z++;
            zhuanhuan1(k);
            int c;
            c=a[z][0];
            a[z][0]=a[z][1];
            a[z][1]=c;
            z--;
        }
    }
    if(z==3)
    {
        switch(k)
        {
        case 0:
            result1[h]=findmax(a[0][0],a[1][0],a[2][0],a[3][0]);
            result2[h]=a[0][1]+a[1][1]+a[2][1]+a[3][1];
            result[h]=result1[h]*result2[h];
            h++;
            break;
        case 1:
            result1[h]=findmax(a[0][0]+a[1][0]+a[2][0],a[3][0]);
            result2[h]=findmax(a[0][1],a[1][1],a[2][1])+a[3][1];
            result[h]=result1[h]*result2[h];
            h++;
            break;
        case 2:
            result1[h]=findmax(a[0][0]+a[1][0],a[2][0])+a[3][0];
            result2[h]=findmax(a[0][1]+a[2][1],a[1][1]+a[2][1],a[3][1]);
            result[h]=result1[h]*result2[h];
            h++;
            break;
        case 3:
            result1[h]=findmax(a[3][0],a[2][0])+a[0][0]+a[1][0];
            result2[h]=findmax(a[0][1],a[3][1]+a[2][1],a[1][1]);
            result[h]=result1[h]*result2[h];
            h++;
            break;
        case 4:
            if(a[2][0]>=(a[1][0]+a[3][0]))
            {
                result1[h]=findmax((a[0][0]+a[2][0]),(a[1][0]+a[3][0]));
                result2[h]=findmax(a[0][1],(a[3][1]+a[2][1]),(a[1][1]+a[2][1]));
                result[h]=result1[h]*result2[h];
                h++;
                break;
            }
            if(a[2][0]>a[3][0]&&a[2][0]<(a[1][0]+a[3][0]))
            {

               result1[h]=findmax((a[0][0]+a[2][0]),(a[1][0]+a[3][0]));
                result2[h]=findmax((a[0][1]+a[1][1]),(a[3][1]+a[2][1]),(a[1][1]+a[2][1]));
                result[h]=result1[h]*result2[h];
                h++;
                break;
            }
            if(a[3][0]>a[2][0]&&a[3][0]<(a[2][0]+a[0][0]))
            {


                result1[h]=findmax((a[0][0]+a[2][0]),(a[1][0]+a[3][0]));
                result2[h]=findmax((a[0][1]+a[1][1]),(a[3][1]+a[0][1]),(a[3][1]+a[2][1]));
                result[h]=result1[h]*result2[h];
                h++;
                break;
            }
            if(a[3][0]>=(a[0][0]+a[2][0]))
            {

                result1[h]=findmax((a[0][0]+a[2][0]),(a[1][0]+a[3][0]));
                result2[h]=findmax((a[0][1]+a[3][1]),(a[3][1]+a[2][1]),a[1][1]);
                result[h]=result1[h]*result2[h];
                h++;
                break;
            }
            if(a[2][0]==a[3][0])
            {

                result1[h]=findmax((a[0][0]+a[2][0]),(a[1][0]+a[3][0]));
                result2[h]=findmax((a[0][1]+a[1][1]),(a[2][1]+a[3][1]));
                result[h]=result1[h]*result2[h];
                h++;
                break;
            }
        }
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值