POJ1017-Packets

15 篇文章 0 订阅

题目大意是某公司有不同规格的产品1*1,2*2,3*3,4*4,5*5,6*6。

要将这些产品放入几个大小为6*6的包裹,问最少需要几个包裹。

感谢Discuss和百度上大神们的优秀算法。

首先最好能填满每个包裹或使包裹最后剩余空间越少越好,且每个包裹装的产品越多越好。

总的来说每个6*6,5*5,4*4的产品放入一个包裹,将几个3*3的产品放入一个包裹,包裹的剩余空间先用2*2的填充,再放入所有1*1的产品。

每个6*6产品独占一个包裹,没有剩余。

每个5*5产品放入一个包裹,剩余可放11个1*1的产品。

每个4*4产品放入一个包裹,剩余可放5个2*2的产品。

每4个3*3产品放入一个包裹,3*3的产品数n就会出现四种情况:

n % 4 == 0,没有剩余。

n % 4 == 1,剩余可放5个2*2和7个1*1。(你可能认为最多可放6个2*2和3个1*1,但事实上在一个6*6的格子中放入3*3后最多只能放5个2*2)

n % 4 == 2,剩余可放3个2*2和6个1*1。

n % 4 == 3,剩余可放1个2*2和5个1*1。

用2*2填充现有包裹,不够的话再开一个包裹。

再用1*1填充。

#include <cstdio>

int main()
{
    int npack[7];
    
    while (1) {
        int i;
        for (i = 1; i <= 6; i++) {
            scanf("%d", &npack[i]);
        }
        if (npack[1] == 0 && npack[2] == 0 && npack[3] == 0
            && npack[4] == 0 && npack[5] == 0 && npack[6] == 0) {
            break;
        }
        
        int sit3[4] = {0, 5, 3, 1};
        int cnt = npack[6] + npack[5] + npack[4] + (npack[3] + 3) / 4;
        
        int rest2 = npack[4] * 5 + sit3[npack[3] % 4];
        if (npack[2] > rest2) {
            cnt += (npack[2] - rest2 + 8) / 9;
        }
        
        int rest1 = 36 * cnt
        - 36 * npack[6] - 25 * npack[5]- 16 * npack[4] - 9 * npack[3]- 4 * npack[2];
        if (npack[1] > rest1) {
            cnt += (npack[1] - rest1 + 35) / 36;
        }
        
        printf("%d\n", cnt);
    }
    
    return 0;
}

另外,x / n向上取整可用(x + n - 1) / n。

当x / n时,余数位于[1, n-1].

当x + n - 1时,余数可看作[n, 2n -1].

这样利用计算机截尾的特性可起到向上取整的作用。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值