• ybt1226 装箱问题


    ybt1226 装箱问题

    【题目描述】

    一个工厂制造的产品形状都是长方体,它们的高度都是h,长和宽都相等,一共有六个型号,他们的长宽分别为1×1,2×2,3×3,4×4,5×5,6×6。这些产品通常使用一个6×6×h的长方体包裹包装然后邮寄给客户。因为邮费很贵,所以工厂要想方设法的减小每个订单运送时的包裹数量。他们很需要有一个好的程序帮他们解决这个问题从而节省费用。现在这个程序由你来设计。

    【输入】

    输入文件包括几行,每一行代表一个订单。每个订单里的一行包括六个整数,中间用空格隔开,分别为1×1至6×6这六种产品的数量。输入文件将以6个0组成的一行结尾。

    【输出】

    除了输入的最后一行6个0以外,输入文件里每一行对应着输出文件的一行,每一行输出一个整数代表对应的订单所需的最小包裹数。

    【输入样例】

    0 0 4 0 0 1 
    7 5 1 0 0 0 
    0 0 0 0 0 0 
    

    【输出样例】

    2 
    1
    

    【题解】

    和乌鸦喝水放石头一个道理,先放大的,再放小的.

    从大到小分析,6*6的箱子直接占满,所以ans+=a[6],不留空隙

    5*5的箱子只能放一个,ans+=a[5]空隙只能放最小的箱子11个.

    4*4的箱子也是只放一个,ans+=a[4],空隙可以放第二小的箱子5个,如果第二小的箱子放完了,就把剩下的空隙放最小的箱子.

    3*3的箱子可以放四个.如果最后有结余,那么就视情况放第二小的箱子最小的箱子(第2小的优先).

    根据3*3箱子的数量分类讨论,情况可以分为:

    1个3*3,最多放5个第二小的箱子,剩下的空隙放最小的.

    2个3*3,最多放3个.

    3个3*3,最多1个.

    找出规律:最后空隙可以塞下的2*2箱子数量为:2(3-a[3]%4)-1

    最后,如果2*2的箱子还有结余,那么ans+=a[2]/9(能放9个)

    如果不能整除,就再加一个容器装最后的余数,剩余空隙用1*1箱子补齐.

    最后的1*1的箱子如果还没放完,直接满满地放,放完为止.

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    int a[7], ans = 0, t;
    bool flag = 0;
    int main() {
    	for (int i = 1; i <= 6; i++) {
    		scanf("%d", &a[i]);
    		if (a[i]) {
    			flag = 1;//只要非0,就打标记
    		}
    	}
    	while (flag) {//只要有一个数不为零,就继续执行
    		flag = 0;//清空标记
    		ans = 0;//答案归零
    		ans += a[6];//6*6的箱子直接放满
    		if (a[5] > 0) {//5*5的箱子
    			a[1] -= 11 * a[5];//只能放得开1*1的箱子
    			ans += a[5];
    		}
    		if (a[4] > 0) {
    			ans += a[4];
    			t = a[2] - (a[4] * 5);
    			if (t <= 0) {//2*2的箱子全部放完
    				a[1] -= (a[4] * 20) - a[2] * 4;//剩余空隙放1*1
    				a[2] = 0;
    			}
    			else {//空隙填满2*2的箱子
    				a[2] -= a[4] * 5;
    			}
    		}
    		if (a[3] > 0) {//处理3*3的格子
    			ans += a[3] / 4;
    			a[3] %= 4;//4个3*3不留空隙
    			if (a[3]) {
    				ans++;
    				t = (4 - a[3]) * 2 - 1;//这就是前面分析的当已经放a[3]个3*3的箱子时,空隙最多能放的2*2的箱子数量.
    				if (a[2] > t) {//放满2*2
    					a[2] -= t;//最大限度放2*2
    					a[1] -= 36 - 9 * a[3] - t * 4;//空隙填满1*1
    				}
    				else {//空隙放完2*2的箱子
    					a[2] = 0;
    					a[1] -= 36 - 9 * a[3] - a[2] * 4;//剩余空隙放1*1的
    				}
    			}
    		}
    		if (a[2] > 0) {//到这里还有2*2的箱子
    			ans += a[2] / 9;
    			if (a[2] % 9) {
    				ans++;
    				a[1] -= 36 - ((a[2] % 9) * 4);
    			}
    		}
    		if (a[1] > 0) {//到这里还有1*1的箱子
    			ans += a[1] / 36;//
    			if (a[1] % 36) {
    				ans++;
    			}
    		}
    		printf("%d
    ", ans);//输出答案
    		for (int i = 1; i <= 6; i++) {//进行下一轮输入
    			scanf("%d", &a[i]);
    			if (a[i]) {
    				flag = 1;
    			}
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    第六周Java学习总结
    结对编程练习_四则运算(一)
    实验一Java开发环境的熟悉
    第四周Java学习总结
    第三周Java学习总结
    2019-2020-2 20175230滕星《网络对抗技术》Exp9 Web安全基础
    2019-2020-2 20175230 滕星《网络对抗技术》Exp 8 Web基础
    2019-2020-2 20175230滕星《网络对抗技术》Exp7 网络欺诈防范
    2019-2020-2 网络对抗技术 20175230滕星 Exp6 MSF基础应用
    2019-2020-2 网络对抗技术 20175230滕星 Exp5 信息搜集与漏洞扫描
  • 原文地址:https://www.cnblogs.com/Wild-Donkey/p/12336537.html
Copyright © 2020-2023  润新知