zoukankan      html  css  js  c++  java
  • 贪心-放置雷达

    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()


  • 相关阅读:
    [#]
    Windows 下配置 ApacheBench (AB) 压力测试
    [转载]
    Nginx 系列教程
    设置外接显示器顺序(哪个在左,哪个在右)的方法
    [.Net] 一句话Linq(递归查询)
    [Xamarin]
    [SVN]
    [SQL SERVER]
    [Oracle]
  • 原文地址:https://www.cnblogs.com/an-wl/p/13485411.html
Copyright © 2011-2022 走看看