小E的射击训练 | 豆包MarsCode AI刷题

77 阅读3分钟

题目描述

image.png

分析

条件分析

首先,我们来明确题目的条件和要求:

  1. 靶心与环的分布: 靶心位于坐标原点 (0, 0),而靶上共有 10 个同心圆环,每个环对应一个分数。靶心内的区域,即半径为 1 的圆,得分为 10 分,之后每个环分数逐渐减少 1 分,直到最后一个环(半径为 10),其得分为 1 分。
  2. 得分规则: 如果射击点位于某个半径为 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。