执行结果:通过
执行用时和内存消耗如下:
int compare(const void* a, const void* b) {
return (*(int*)b - *(int*)a);
}
long long minimumCost(int m, int n, int* horizontalCut, int horizontalCutSize, int* verticalCut, int verticalCutSize) {
qsort(horizontalCut, horizontalCutSize, sizeof(int), compare);
qsort(verticalCut, verticalCutSize, sizeof(int), compare);
long long h = 1, v = 1;
long long res = 0;
int hIndex = 0, vIndex = 0;
while (hIndex < horizontalCutSize || vIndex < verticalCutSize) {
if (vIndex == verticalCutSize || (hIndex < horizontalCutSize && horizontalCut[hIndex] > verticalCut[vIndex])) {
res += horizontalCut[hIndex++] * h;
v++;
} else {
res += verticalCut[vIndex++] * v;
h++;
}
}
return res;
}
解题思路:
这段代码的目的是计算将一块矩形面板(尺寸为 m×n)通过水平和垂直切割所需的最小成本。面板可以通过给定数量的水平和垂直切割线来分割。每种切割方式的成本等于切割线长度乘以它所在的较小面板的数量(在切割方向上的面板数量)。下面详细解释这段代码的思路:
- 比较函数
compare
:- 这是一个用于
qsort
排序的比较函数。 - 它接收两个
const void*
类型的参数a
和b
,代表要比较的两个元素。 - 函数通过类型转换将
void*
转换为int*
,然后解引用以获得实际的值。 - 返回
*(int*)b - *(int*)a
,意味着以降序对整数进行排序。
- 这是一个用于
- 函数
minimumCost
:- 参数说明:
m
和n
分别表示矩形面板的宽度和高度。horizontalCut
和verticalCut
是两个数组,分别存储所有水平切割线和垂直切割线的位置。horizontalCutSize
和verticalCutSize
分别是horizontalCut
和verticalCut
数组的大小。
- 思路:
- 排序切割线:
- 使用
qsort
函数和compare
比较函数,分别对水平和垂直切割线进行降序排序。这是为了方便后续遍历和计算。
- 使用
- 初始化变量:
h
和v
分别表示当前面板在水平和垂直方向上的分割数量(初始化为1,因为面板本身就是一个完整的区域)。res
用于存储总成本,初始化为0。hIndex
和vIndex
分别用于遍历水平和垂直切割线的索引。
- 遍历切割线:
- 使用一个
while
循环,直到所有水平和垂直切割线都被遍历完毕。 - 在每次迭代中,比较当前遍历到的水平切割线(如果存在)和垂直切割线(如果存在)的位置。
- 如果当前水平切割线的位置大于或等于当前垂直切割线的位置(或者没有更多的垂直切割线),则处理水平切割线:
- 将当前水平切割线的位置乘以水平方向上的面板数量
h
,并累加到总成本res
上。 - 垂直方向上的面板数量
v
增加1(因为添加了一条水平切割线)。 - 水平切割线索引
hIndex
增加1。
- 将当前水平切割线的位置乘以水平方向上的面板数量
- 否则,处理垂直切割线:
- 将当前垂直切割线的位置乘以垂直方向上的面板数量
v
,并累加到总成本res
上。 - 水平方向上的面板数量
h
增加1(因为添加了一条垂直切割线)。 - 垂直切割线索引
vIndex
增加1。
- 将当前垂直切割线的位置乘以垂直方向上的面板数量
- 使用一个
- 返回结果:
- 循环结束后,返回总成本
res
。
- 循环结束后,返回总成本
- 排序切割线:
- 参数说明:
这个算法的关键在于通过排序来简化切割线的处理,并使用两个指针(或索引)来同时遍历水平和垂直切割线,确保每次处理的都是当前最短(因为已排序)的切割线,从而得到最小的成本。