搜狐2018研发工程师秋招笔试题

题目

有一间工厂生产的东西, 被包装在相同高度h 的正方形容器内, 但其面积大小分别有:1*1, 2*2, 3*3, 4*4, 5*5, 6*6等六种尺寸。这些产品总是用高度为h,面积为6*6的箱子打包后寄给客户。因为成本关系,当然希望将客户所订购的产品放在最少的箱子里寄出。请你写一个程式找出寄送这些产品最少需要多少个箱子,这可以使工厂节省下不少钱.

思路

简单的暴力贪心算法,对不同的产品有不同的策略,按照从大到小的顺序打包产品,策略如下:


  • 6*6:1个产品放在1个箱子里
  • 5*5:1个产品要占用1个箱子,用1*1的箱子可以填充(11个填满1箱)
  • 4*4:1个产品要占用1个箱子,剩余空间用2*2和1*1的箱子填充(先填充2*2,再填充1*1)
  • 3*3:4个产品可以填满1个箱子,假如有不满1个箱子的,分情况用1*1和2*2的产品填满
  • 2*2:9个产品可以填满1个箱子,假如有不满1个箱子的,用1*1的产品填充
  • 1*1:36个产品可填满一个箱子

代码

#include<iostream>
#include<algorithm>
using namespace std;
int arry[10];
int main()
{
    while(cin>>arry[1]>>arry[2]>>arry[3]>>arry[4]>>arry[5]>>arry[6])
    {
        if(arry[1]==0&&arry[2]==0&&arry[3]==0&&arry[4]==0&&arry[5]==0&&arry[6]==0) break;
        int sum=arry[6];
        while(arry[5]>0) //大小为5*5的只能与1*1的搭配
        {
            sum++;
            arry[5]--;
            if(arry[1]>=11) arry[1]=arry[1]-11;
            else if(arry[1]<11&&arry[1]>0) arry[1]=0;
        }
        while(arry[4]>0)
        {
            sum++;
            arry[4]--;
            if(arry[2]>0) //4*4只能与2*2,1*1搭配,当2*2的还有时优先与2*2的搭配
            {
                if(arry[2]>=5) arry[2]=arry[2]-5;
                else if(arry[2]<5)
                {
                    int remain=20-4*arry[2];
                    arry[2]=0;
                    if(arry[1]>0) //当2*2不足时与1*1搭配
                    {
                        if(arry[1]<remain) arry[1]=0;
                        else arry[1]=arry[1]-remain;
                    }
                }
            }
            else //当2*2不足时与1*1搭配
            {
                if(arry[1]>=20) arry[1]=arry[1]-20;
                else arry[1]=0;
            }
        }
        while(arry[3]>0) //3*3的搭配种类比较多而且较为麻烦,要分别考虑能放下多少个3*3的盒子
        {
            sum++;
            int remain,num;
            if(arry[3]>=4) arry[3]=arry[3]-4,remain=0,num=4;
            else remain=36-arry[3]*9,num=arry[3],arry[3]=0;
            if(num==4) continue;
            else if(num==1)
            {
                if(arry[2]>=5) //先与2*2搭配
                {
                    arry[2]=arry[2]-5;
                    remain=remain-20;
                    if(remain<arry[1]) arry[1]=arry[1]-remain;//再与1*1搭配
                    else arry[1]=0;
                }
                else //与1*1搭配
                {
                    remain=remain-arry[2]*4;
                    arry[2]=0;
                    if(remain>=arry[1]) arry[1]=0;
                    else arry[1]=arry[1]-remain;
                }
            }
            else if(num==2)
            {
                if(arry[2]>=3)
                {
                    arry[2]=arry[2]-3;
                    remain=remain-12;
                    if(remain<arry[1]) arry[1]=arry[1]-remain;
                    else arry[1]=0;
                }
                else
                {
                    remain=remain-arry[2]*4;
                    arry[2]=0;
                    if(remain>=arry[1]) arry[1]=0;
                    else arry[1]=arry[1]-remain;
                }
            }
            else if(num==3)
            {
                if(arry[2]>=1)
                {
                    arry[2]=arry[2]-1;
                    remain=remain-4;
                    if(remain<arry[1]) arry[1]=arry[1]-remain;
                    else arry[1]=0;
                }
                else
                {
                    remain=remain-arry[2]*4;
                    arry[2]=0;
                    if(remain>=arry[1]) arry[1]=0;
                    else arry[1]=arry[1]-remain;
                }
            }
        }
        while(arry[2]>0) //2*2的盒子只能与1*1的盒子搭配。
        {
            sum++;
            if(arry[2]>=9) arry[2]=arry[2]-9;
            else
            {
                int remain=36-arry[2]*4;
                arry[2]=0;
                if(remain>arry[1]) arry[1]=0;
                else arry[1]=arry[1]-remain;
            }
        }
        while(arry[1]>0)
        {
            sum++;
            if(arry[1]>=36) arry[1]=arry[1]-36;
            else arry[1]=0;
        }
        cout<<sum<<endl;
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值