青训营X豆包MarsCode 技术训练AI刷题小E的设计训练 | 豆包MarsCode AI 刷题

55 阅读4分钟

问题描述

小E正在训练场进行射击练习,靶有10个环,靶心位于坐标(0, 0)。每个环对应不同的得分,靶心内(半径为1)得10分,依次向外的每个环分数减少1分。若射击点在某个半径为i的圆内,则得11-i分。如果射击点超出所有的环,则得0分。

根据给定的射击坐标(x, y),请计算小E的射击得分。


测试样例

样例1:

输入:x = 1, y = 0
输出:10

样例2:

输入:x = 1, y = 1
输出:9

样例3:

输入:x = 0, y = 5
输出:6

样例4:

输入:x = 3, y = 4
输出:6

解题思路

  1. 靶心和环的定义

    • 靶心位于坐标 (0, 0)
    • 靶心内(半径为1)得10分。
    • 依次向外的每个环分数减少1分。
    • 如果射击点超出所有的环,则得0分。
  2. 得分计算

    • 计算射击点 (x, y) 到靶心 (0, 0) 的距离。

    • 根据距离确定得分:

      • 距离在半径为1的圆内,得10分。
      • 距离在半径为2的圆内,得9分。
      • 以此类推,直到距离在半径为10的圆内,得1分。
      • 如果距离大于10,得0分。

数据结构和算法步骤

  1. 计算距离

    • 使用欧几里得距离公式计算 (x, y) 到 (0, 0) 的距离。
  2. 确定得分

    • 根据距离确定得分:

      • 如果距离小于等于1,得10分。
      • 如果距离大于1且小于等于2,得9分。
      • 以此类推,直到距离大于10,得0分。

代码

def solution(x: int, y: int) -> int:
     # write code here
     dis = (x ** 2 + y ** 2) ** 0.5
     if dis - int(dis) > 0:
         score = 10 - int(dis)
     else:
         score = 11 - int(dis)
     return max(0, score)

if __name__ == '__main__':
    print(solution(1, 0) == 10)
    print(solution(1, 1) == 9)
    print(solution(0, 5) == 6)
    print(solution(3, 4) == 6)

复杂度分析

时间复杂度分析

  1. 计算距离

    • dis = (x ** 2 + y ** 2) ** 0.5

      • x ** 2 和 y ** 2 是常数时间操作。
      • (x ** 2 + y ** 2) ** 0.5 是常数时间操作。
    • 因此,计算距离的时间复杂度是 O(1)

  2. 确定得分

    • int(dis) 是常数时间操作。
    • if dis - int(dis) > 0 是常数时间操作。
    • score = 10 - int(dis) 或 score = 11 - int(dis) 是常数时间操作。
    • return max(0, score) 是常数时间操作。
    • 因此,确定得分的时间复杂度是 O(1)

空间复杂度分析

  1. 变量存储

    • dis 存储距离,占用常数空间。
    • score 存储得分,占用常数空间。
    • 因此,空间复杂度是 O(1)

总结

  • 时间复杂度:O(1)
  • 空间复杂度:O(1)

优化思路

优化思路

  1. 简化得分计算逻辑

    • 当前代码中,if dis - int(dis) > 0 的逻辑可以简化为直接使用 int(dis) 来计算得分。
  2. 减少不必要的计算

    • 当前代码中,dis - int(dis) > 0 的判断是为了处理浮点数精度问题,但实际上可以直接使用 int(dis) 来计算得分。
  3. 提高代码可读性

    • 使用更具描述性的变量名,例如 distance 而不是 dis
    • 使用常量来表示最大得分和最小得分,以提高代码的可维护性。

好的,让我们来总结一下这个题目和代码。

题目总结

问题描述

小E正在训练场进行射击练习,靶有10个环,靶心位于坐标 (0, 0)。每个环对应不同的得分,靶心内(半径为1)得10分,依次向外的每个环分数减少1分。若射击点在某个半径为 i 的圆内,则得 11-i 分。如果射击点超出所有的环,则得0分。

测试样例

  • 输入:x = 1, y = 0,输出:10
  • 输入:x = 1, y = 1,输出:9
  • 输入:x = 0, y = 5,输出:6
  • 输入:x = 3, y = 4,输出:6

代码总结

代码分析

  1. 计算距离

    • 使用欧几里得距离公式 dis = (x ** 2 + y ** 2) ** 0.5 计算射击点 (x, y) 到靶心 (0, 0) 的距离。
  2. 确定得分

    • 根据距离 dis 确定得分:

      • 如果 dis - int(dis) > 0,则得分 score = 10 - int(dis)
      • 否则,得分 score = 11 - int(dis)
    • 最后使用 max(0, score) 确保得分不小于0。

优化后的代码

def solution(x: int, y: int) -> int:

    distance = (x ** 2 + y ** 2) ** 0.5

    

    if distance <= 1:

        score = 10

    elif distance <= 2:

        score = 9

    elif distance <= 3:

        score = 8

    elif distance <= 4:

        score = 7

    elif distance <= 5:

        score = 6

    elif distance <= 6:

        score = 5

    elif distance <= 7:

        score = 4

    elif distance <= 8:

        score = 3

    elif distance <= 9:

        score = 2

    elif distance <= 10:

        score = 1

    else:

        score = 0

    

    return score

if __name__ == '__main__':

    print(solution(10) == 10)

    print(solution(11) == 9)

    print(solution(05) == 6)

    print(solution(34) == 6)

优化点

  1. 简化得分计算逻辑

    • 直接使用 if-elif-else 结构来计算得分,避免了浮点数精度问题。
  2. 提高代码可读性

    • 使用 distance 代替 dis,使变量名更具描述性。
    • 使用 if-elif-else 结构,使代码逻辑更清晰。