让【道友老李】来帮你解答,本回答参考通义千问qwen-plus编写,并整理提供,如果还有疑问可以点击头像关注,评论或留言
要解决这个问题,我们可以使用贪心算法。具体思路是每次选择能够覆盖最远距离的摄像头,这样可以最大限度地减少摄像头的数量。
算法步骤:
- 初始化:读取输入数据,包括只因窝的数量 ( N ) 和每个只因窝的观测范围 ( a_i )。
- 排序:将只因窝按其左边界从小到大排序,如果左边界相同,则按右边界从大到小排序。
- 贪心选择:从左到右遍历排序后的只因窝,每次选择能够覆盖最远距离的摄像头,并更新当前已覆盖的最大位置。
- 统计结果:记录所需的摄像头数量。
具体实现:
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int left;
int right;
} Range;
// 比较函数,用于qsort排序
int compare(const void *a, const void *b) {
Range *rangeA = (Range *)a;
Range *rangeB = (Range *)b;
if (rangeA->left == rangeB->left) {
return rangeB->right - rangeA->right;
}
return rangeA->left - rangeB->left;
}
int minCameras(int N, int *a) {
Range ranges[N];
// 计算每个只因窝的观测范围
for (int i = 0; i < N; i++) {
ranges[i].left = i - a[i];
ranges[i].right = i + a[i];
}
// 按左边界排序,如果左边界相同,则按右边界从大到小排序
qsort(ranges, N, sizeof(Range), compare);
int cameras = 0;
int currentRight = -1;
// 遍历排序后的范围
for (int i = 0; i < N; i++) {
if (ranges[i].left > currentRight) {
// 当前范围无法被覆盖,需要一个新的摄像头
cameras++;
currentRight = ranges[i].right;
}
}
return cameras;
}
int main() {
int N;
scanf("%d", &N);
int a[N];
for (int i = 0; i < N; i++) {
scanf("%d", &a[i]);
}
int result = minCameras(N, a);
printf("%d\n", result);
return 0;
}
解释:
- Range 结构体:用于存储每个只因窝的观测范围。
- compare 函数:用于
qsort 排序,确保按左边界从小到大排序,如果左边界相同,则按右边界从大到小排序。 - minCameras 函数:
- 计算每个只因窝的观测范围。
- 使用
qsort 对观测范围进行排序。 - 遍历排序后的范围,使用贪心策略选择摄像头。
- main 函数:
- 读取输入数据。
- 调用
minCameras 函数计算最小摄像头数量。 - 输出结果。
这个算法的时间复杂度主要由排序决定,为 ( O(N \log N) ),适合处理题目给定的数据规模。