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

122 阅读3分钟

问题解析

题目要求

给定射击点的坐标 (x,y),靶心位于 (0,0)。靶由同心圆构成,每个环的半径依次增加 1,中心环(半径为 1)得分最高,为 10,依次向外环得分递减 1。若点超出最外层环(半径为 10),得分为 0。

评分规则

如果点落在某个半径 ii 的圆内,得分为 11−i; 若点的欧几里得距离大于 10,得分为 0。

目标

通过计算点到靶心的欧几里得距离,判断点在哪个环中,从而确定分数。


解题思路

1. 计算距离

使用欧几里得距离公式: 距离= sqrt(x^2 + y^2) 这是点与圆心的直线距离,用于判断点与各个圆的关系。

计算欧几里得距离,why

在这道题中,我们需要根据射击点与靶心的距离判断得分,而欧几里得距离是最直观、符合物理意义的距离度量方式,能够准确表示点与靶心之间的直线距离。


1. 圆的几何特性

靶是由同心圆构成的,每个环的半径 r 是判断分数的关键参数。 圆的几何性质规定:点与圆心的距离小于圆的半径时,点在圆内

欧几里得距离公式:

距离=sqrt((x - x0)^2 + (y - y0)^2)

对于此题,靶心的坐标是 (0,0),距离简化为:

距离=sqrt(x^2 + y^2)

通过计算射击点到靶心的欧几里得距离,可以直接比较这个距离与每个圆的半径,快速判断射击点属于哪个环。


2. 其他距离度量方式的局限性

如果不使用欧几里得距离,其他方式可能会出现问题:

  • 曼哈顿距离: 曼哈顿距离是基于网格的度量方式,计算公式为:

    距离=∣x−x0∣+∣y−y0∣

    这种方式在计算方形或网格区域时有效,但在圆形区域中无法准确反映点与圆心的关系。

故欧几里得距离是圆形靶这种场景下的最适合度量方法

采用欧几里得距离:

直接反映点与圆心的几何关系。

符合题目和现实中的得分规则。

计算效率高且实现简单。

2. 判断环位置

按环半径从 1 到 10 遍历。 若计算出的距离小于当前环的半径,说明点在该环内,立即返回得分 11−环编号i。

3. 超出所有环

如果点的距离大于 10,即点不在任何环内,返回得分 0。


关键代码解析

import math
  • 导入 math 模块,使用平方根函数 math.sqrt() 计算欧几里得距离。
distance = math.sqrt(x ** 2 + y ** 2)
  • 使用欧几里得公式计算点与靶心的距离。
for i in range(1, 11):  # 环编号从110
    if distance < i:
        return 11 - i
  • 从第一个环(半径为 1)开始,依次判断距离是否小于环的半径。
  • 若满足条件,直接返回得分 11−环编号i。
  • 提前结束遍历,保证效率。
return 0
  • 当遍历完所有环后,若距离依然大于 10,说明点在靶外,返回 0。

注意点

1. 边界条件

若点刚好落在某个环的边界(如 距离=a),根据题意得分按在半径为a的环处理,故代码中采用 "<=" 判断。

2. 输入范围

-   x , y 的值可能较大,但只需计算其平方和后开方

完整代码

import math

def solution(x: int, y: int) -> int:
    # 计算点到靶心的欧几里得距离
    distance = math.sqrt(x ** 2 + y ** 2)
    
    # 判断得分
    for i in range(1, 11):  # 环编号从1到10
        if distance < i:
            return 11 - i
    
    # 超出所有环,得分为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)   

总结

  • 时间复杂度:O(1)(因为最多遍历 10 个环,常数时间)。
  • 空间复杂度:O(1)(只需存储距离和环编号)。