题目描述
一个快递公司希望在一条街道建立新的服务中心。公司统计了该街道中所有区域在地图上的位置,并希望能够以此为依据为新的服务中心选址:使服务中心到所有区域的距离的总和最小。
给你一个数组positions,其中positions[i] = [left, right] 表示第 i 个区域在街道上的位置,其中left代表区域的左侧的起点,right代表区域的右侧终点,假设服务中心的位置为location:
- 如果第 i 个区域的右侧终点right满足 right < location,则第 i 个区域到服务中心的距离为 location - right;
- 如果第 i 个区域的左侧起点left 满足 left > location,则第 i 个区域到服务中心的距离为left - location;
- 如果第 i 个区域的两侧left,right满足left <= location <= right,则第 i 个区域到服务中心的距离为0
选择最佳的服务中心位置为location,请返回最佳的服务中心位置到所有区域的距离总和的最小值。
输入描述
先输入区域数组positions的长度n(1 ≤ n ≤ 10^5)
接下来 n 行每行输入成对的left和right值,以空格隔开
- -10^9 <left ≤ 10^9
- -10^9 <right ≤ 10^9
输出描述
输出为location
用例
| 输入 | 4 5 6 1 8 7 15 2 4 |
| 输出 | 3 |
| 说明 | 无 |
| 输入 | 6 1 3 4 9 2 15 6 27 15 17 5 8 |
| 输出 | 12 |
| 说明 | 无 |
| 输入 | 16 41 67 0 34 24 69 58 78 62 5 45 27 81 61 91 42 95 27 36 4 91 2 53 82 92 16 21 18 95 26 47 |
| 输出 | 127 |
| 说明 | 无 |
解析
题目要求在街道上找到一个位置,使得这个位置到所有区域的距离之和最小。每个区域用一个 [left, right] 的区间表示,要求找到一个最佳的 location,使得所有区域到这个位置的距离之和最小。
解决思路:
C语言代码实现
以下是根据上述思路的C语言代码实现:
#include <stdio.h>
#include <stdlib.h>
#define ll long long
// 计算给定location时,所有区域到该location的总距离
ll calculate_total_distance(int location, int positions[][2], int n) {
ll total_distance = 0;
for (int i = 0; i < n; i++) {
if (location < positions[i][0]) {
total_distance += positions[i][0] - location;
} else if (location > positions[i][1]) {
total_distance += location - positions[i][1];
}
}
return total_distance;
}
int main() {
int n;
scanf("%d", &n);
int positions[n][2];
for (int i = 0; i < n; i++) {
scanf("%d %d", &positions[i][0], &positions[i][1]);
}
// 二分查找
int left = -1000000000;
int right = 1000000000;
while (left < right) {
int mid1 = left + (right - left) / 3;
int mid2 = right - (right - left) / 3;
ll dist1 = calculate_total_distance(mid1, positions, n);
ll dist2 = calculate_total_distance(mid2, positions, n);
if (dist1 < dist2) {
right = mid2 - 1;
} else {
left = mid1 + 1;
}
}
printf("%d\n", left);
return 0;
}
代码说明
- 函数
calculate_total_distance: 计算给定 location 时所有区域到该 location 的总距离。 - 二分查找: 使用三分法在可能的
location 范围内查找,使得总距离最小的 location。 - 输入部分: 输入区域的数量
n 和每个区域的 [left, right] 区间。 - 输出部分: 输出最优的
location。
Python 代码实现
将上述C语言代码转换成Python代码如下:
def calculate_total_distance(location, positions):
total_distance = 0
for left, right in positions:
if location < left:
total_distance += left - location
elif location > right:
total_distance += location - right
return total_distance
def find_best_location(positions):
left, right = -10**9, 10**9
while left < right:
mid1 = left + (right - left) // 3
mid2 = right - (right - left) // 3
dist1 = calculate_total_distance(mid1, positions)
dist2 = calculate_total_distance(mid2, positions)
if dist1 < dist2:
right = mid2 - 1
else:
left = mid1 + 1
return left
# 输入部分
n = int(input())
positions = [tuple(map(int, input().split())) for _ in range(n)]
# 找到最优的 location
best_location = find_best_location(positions)
# 输出结果
print(best_location)
代码说明
- 函数
calculate_total_distance: 计算给定 location 时所有区域到该 location 的总距离。 - 函数
find_best_location: 使用三分法查找最佳 location,使得总距离最小。 - 输入部分: 接收
n 个区间 [left, right] 的输入。 - 输出部分: 输出最优的
location。