题目描述
分析
条件分析
首先,我们来明确题目的条件和要求:
- 靶心与环的分布: 靶心位于坐标原点 (0, 0),而靶上共有 10 个同心圆环,每个环对应一个分数。靶心内的区域,即半径为 1 的圆,得分为 10 分,之后每个环分数逐渐减少 1 分,直到最后一个环(半径为 10),其得分为 1 分。
- 得分规则: 如果射击点位于某个半径为 i 的圆内,那么它的得分为 11-i 分。超过最大的环(即半径为 10 的环),则得 0 分。
靶心的位置是坐标 (0, 0),每个环的半径从 1 到 10 不等。具体来说:
- 半径为 1 的圆,得分 10 分;
- 半径为 2 的圆,得分 9 分;
- 以此类推,直到半径为 10 的圆,得分为 1 分;
- 超出所有环的点,得分为 0 分。
例如,如果射击点 (1, 0) 落在半径为 1 的圆上(其实就是在圆上),那么该点的得分应为 10 分。如果点 (1, 1) 落在半径为 2 的圆内,那么得分为 9 分。
思路分析
根据题目要求,首先我们需要计算射击点到靶心的距离。假设射击点的坐标为 (x, y),则射击点到靶心 (0, 0) 的距离可以通过欧几里得距离公式计算:
distance = sqrt(x^2 + y^2)。
这个公式很直观,表示了从点 (x, y) 到原点 (0, 0) 的直线距离。
判定得分:
根据计算出来的距离,我们可以判定射击点所处的环的位置。题目给出的规则是,若射击点的距离小于等于某个环的半径,就可以获得该环的对应分数。因此,我们可以通过一系列的判断来为每个距离对应的环分配得分。
判定逻辑:
我们将环的半径和分数放在一个列表中,列表元素的格式是 (radius, score)。然后遍历列表,判断计算出的距离是否落在某个环内。
如果距离小于等于某个半径,直接返回该环对应的分数。如果遍历完整个列表都没有找到合适的环,则返回 0 分(即距离超过了最大半径 10 的环)。
时间复杂度:
由于列表中最多只有 10 个元素(对应 10 个环),因此该算法的时间复杂度是 O(1),即常数时间复杂度。这意味着无论输入是什么,程序的执行时间都非常短。
代码实现
import math
def solution(x: int, y: int) -> int:
# 计算射击点到靶心的距离
distance = math.sqrt(x**2 + y**2)
# 使用列表来存储距离范围和得分
score_ranges = [
(1, 10),
(2, 9),
(3, 8),
(4, 7),
(5, 6),
(6, 5),
(7, 4),
(8, 3),
(9, 2),
(10, 1)
]
# 遍历列表,找到第一个满足条件的得分
for max_distance, score in score_ranges:
if distance <= max_distance:
return score
# 如果距离大于10,返回0分
return 0
if __name__ == '__main__':
print(solution(1, 0) == 10)
print(solution(1, 1) == 9)
print(solution(0, 5) == 6)
print(solution(3, 4) == 6)
测试用例验证
-
输入
(1, 0),计算得到的距离为 1,落在半径为 1 的圆内,因此得分为 10。 -
输入
(1, 1),计算得到的距离为 2\sqrt{2}2,约等于 1.414,落在半径为 2 的圆内,因此得分为 9。 -
输入
(0, 5),计算得到的距离为 5,落在半径为 5 的圆内,因此得分为 6。 -
输入
(3, 4),计算得到的距离为 5,落在半径为 5 的圆内,因此得分为 6。