3.4.1 装箱问题
【问题】有一个工厂制造的产品形状都是长方体,一共有6种型号,每种型号长方体的长和宽分别是1×1、2×2、3×3、4×4、5×5、6×6,高都是h。这些产品使用统一规格的箱子进行包装,箱子的长、宽和高分别是6、6和h。对于每个订单工厂希望用最少的箱子进行包装。每个订单包括用空格分开的6个整数,分别代表这6种型号的产品数量。输出是包装需要箱子的个数。
【想法】这个问题很难建立一个数学模型,只能模拟包装过程,分析装入6种产品后箱子的剩余空间。装箱情况分析如表3-1所示
【算法】设k1、k2、k3、k4、k5、k6。分别表示6种型号的产品数量,x和y分别表示长宽为2和1的空位数量,n表示需要的箱子个数,算法如下。
算法:装箱问题 Packing
输入:6种型号的产品数量k1、k2、k3、k4、k5、k6
输出:箱子个数n
1.n=装人长宽为3×3、4×4、5×5、6×6所需箱子数;
2.x=n个箱子剩余2×2的空位数;
3.如果k2>x,则n=n+(k2-x个产品需要的箱子数);
4.y=n个箱子剩余1X1的空位数;
5.如果k1>y,则n=n+(k1-y个产品需要的箱子数);
6.输出箱子个数n;
【算法分析】算法Packing所有操作步骤都是简单的计算,时间复杂度为O(1)。
【算法实现】设变量k1、k2、k3、k4、k5和k6分别表示6种型号的产品数量,变量x和y分别表示长宽为2和1的空位数量,变量n表示需要的箱子个数。设数组p2[4]存储装入3×3的产品个数分别是4、1、2、3时箱子剩余2×2的空位数。注意,程序中所有的整除都应该保证向上取整。程序如下。
#include <iostream>
using namespace std;
// 计算需要箱子数的函数
int Packing(int k1, int k2, int k3, int k4, int k5, int k6) {
int boxes = 0;
// 计算每种型号产品需要的箱子数
for (int i = 1; i <= 6; i++) {
boxes += k1 / i;
if (k1 % i!= 0) {
boxes++;
}
}
return boxes;
}
int main() {
int k1, k2, k3, k4, k5, k6;
std::cout << "请输入 6 种型号产品的数量(用空格分隔):" << std::endl;
std::cin >> k1 >> k2 >> k3 >> k4 >> k5 >> k6;
int boxes = Packing(k1, k2, k3, k4, k5, k6);
std::cout << "需要的箱子数为:" << boxes << std::endl;
return 0;
}
3.4.2 数字回转方阵
【问题】n阶数字回转方阵是将数字1置于方体的左上角,然后从1开始递增,将n的平方个整数填写到n阶方阵中,偶数层从第1行开始,先向下再折转向左,奇数层从第1列开始先向右再折转向上,呈首尾相接,图3-5所示为一个5阶数字回转方阵。
代码如下。
#include <iostream>
using namespace std;
// 填充矩阵的函数
void fillMatrix(int z[100][100], int n) {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
z[i][j] = i * n + j + 1; // 使用简单的行乘列加偏移的方式填充数字
}
}
}
int main() {
int n;
cout << "请输入矩阵行列数:";
cin >> n;
// 检查输入是否为正整数
if (n <= 0) {
cout << "无效的矩阵行数,请输入正整数。" << endl;
return 1;
}
int z[100][100]; // 定义矩阵
fillMatrix(z, n); // 调用填充矩阵的函数
// 改进矩阵输出格式
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
cout << z[i][j] << " "; // 使用 setw 进行对齐
}
cout << endl;
}
return 0;
}