贪心-放置雷达

Radar Installation:x轴是海岸线, x 轴上方是海洋。海洋中有 n
1<=n<=1000) 个岛屿,可以看作点。给定每个岛屿的坐标(x,y)x,y都是整
数。当一个雷达(可以看作点)到岛屿的距离不超过 d(整数),则认为该雷达
覆盖了该岛屿。雷达只能放在x轴上。问至少需要多少个雷达才可以覆盖全部岛屿。

Sample Input:3个岛,距离d=2,后面3组数描述3个岛的坐标
3 2
1 2
-3 1
2 1

Sample Output:至少需要雷达的数量
2
原理:对每个岛屿P, 可以算出,覆盖它的雷达,必须位于 x 轴上的区间 Ps ,Pe 。
如果有雷达位于某个x轴区间 [a,b ],称该雷达覆盖此区间。问题转换为,
至少要在 x 轴上放几个雷达(点),才能覆盖全部区间 [P1s ,P1e],
[P2s,P2e ……Pns,Pne]
重要结论:如果可以找到一个雷达同时覆盖多个区间,那么把这多个区间按起点坐
标从小到大排序 ,则最后一个区间 起点最靠右的k的起点,就能覆盖所有区间

规则:只需要存储当前右端点的最小值,判断新加入坐标的左端点是否大于当前右端点
的最小值;
1)如果小于等于,则说明可以覆盖,彼此有公共区域,不需要新增雷达,同时需要更新
一下右端点的最小值
2)如果大于,说明没有公共的交点,需要新增雷达,右端点的最小值为新加入的雷达右端点

Python代码实现:
 1 import math
 2 
 3 
 4 def main():
 5     # 雷达的数量
 6     radar_num = 1
 7     # 岛屿列表
 8     island_list = []
 9     n, d = map(int, input().split())
10     for i in range(n):
11         temp = list(map(int, input().split()))
12         # 计算该岛映射到x轴左右端点的值
13         left_pos = temp[0] - math.sqrt(math.pow(d, 2) - math.pow(temp[1], 2))
14         right_pos = temp[0] + math.sqrt(math.pow(d, 2) - math.pow(temp[1], 2))
15         temp.append(round(left_pos, 2))
16         temp.append(round(right_pos, 2))
17         island_list.append(temp)
18     # [[1, 2, 1.0, 1.0],
19     # [-3, 1, -4.73, -1.27],
20     # [2, 1, 0.27, 3.73]]
21     # 以岛屿列表的左端点进行排序
22     island_list = sorted(island_list, key=lambda x: x[2])
23     # 当前岛屿右端点的最小值
24     min_right = island_list[0][3]
25     for i in range(1, n):
26         # 如果新加入的岛屿左端点<这组集合右端点的值,说明可以在同一个雷达覆盖范围
27         # 则不需要新增雷达,此时可能需要更新右端点的最小值
28         if island_list[i][2] <= min_right:
29             min_right = min(min_right, island_list[i][3])
30         # 大于的话,说明不能与前一组岛屿共用同一个雷达,需要新增一个雷达
31         # 右端的最小值也需要重新更新
32         else:
33             min_right = island_list[i][3]
34             radar_num += 1
35 
36     print("至少需要%d个雷达" % radar_num)
37     return 0
38 
39 
40 if __name__ == '__main__':
41     main()

 



posted @ 2020-08-11 21:53  StudyNLP  阅读(217)  评论(0编辑  收藏  举报