小E的射击训练问题
问题描述
小E正在训练场进行射击练习,靶子上有10个环,每个环对应不同的得分。靶心位于坐标 (0, 0),每个环的半径逐渐增大,对应的得分逐渐减少。具体来说,靶心内(半径为1)的得分为10分,接着每个环的得分依次减少1分,直到最外层环(半径为10)得0分。如果射击点位于某个环内,得分为 11 - i,其中 i 表示环的编号(从1到10)。如果射击点超出所有环,则得0分。
给定射击的坐标 (x, y),请计算小E的射击得分。
问题分析
这个问题的关键是计算点 (x, y) 到靶心 (0, 0) 的距离。根据射击点到靶心的距离,决定射击点所在的环,并根据环的编号来返回得分。
具体步骤如下:
- 计算点
(x, y)到原点(0, 0)的距离的平方,即distance_squared = x * x + y * y。这样可以避免使用浮动运算。 - 定义每个环的得分阈值,环的半径逐渐增大,从1到10对应的得分从10分到0分。
- 根据
distance_squared判断点(x, y)位于哪个环内,从而返回相应的得分。
题目等级
难度:基础。属于是理解题意就能写的题
解题思路
- 计算距离:首先,计算射击点
(x, y)到靶心(0, 0)的距离的平方。 - 设置阈值:根据每个环的半径,设定一个距离的阈值。我们不需要计算实际的距离,只需使用距离的平方来判断。
- 根据距离判断得分:从内到外判断射击点是否位于某个环内,若在环内,则返回该环对应的得分。
- 边界条件:如果射击点超出最外层环(即距离平方大于100),则得0分。
代码实现
def solution(x: int, y: int) -> int:
# 计算射击点到原点的距离的平方
distance_squared = x * x + y * y
# 定义每个环的分数阈值(半径的平方)
score_thresholds = [1, 4, 9, 16, 25, 36, 49, 64, 81, 100] # 半径1到10的平方值
# 判断射击点在哪个环内,并返回对应的得分
for i in range(10):
if distance_squared <= score_thresholds[i]:
return 10 - i # 得分是10减去环的编号(从0开始)
# 如果射击点在最外层环之外,则得0分
return 0
# 测试用例
if __name__ == '__main__':
# 测试用例
print(solution(1, 0) == 10) # 期望输出 10
print(solution(1, 1) == 9) # 期望输出 9
print(solution(0, 5) == 6) # 期望输出 6
print(solution(3, 4) == 6) # 期望输出 6
代码讲解
- 计算距离的平方:我们首先计算
(x, y)到原点(0, 0)的距离的平方,避免使用sqrt函数,直接比较距离的平方值。 - 得分阈值:通过
score_thresholds数组定义了每个环的半径的平方(即1^2, 2^2, ..., 10^2)。这样我们只需要判断射击点的distance_squared是否小于等于某个阈值来确定得分。 - 循环判断:从第一个环开始,逐一判断射击点是否落在该环内。如果落在某个环内,则返回该环对应的分数。
- 返回结果:如果射击点超出所有环,则返回0分。
测试样例分析
- 样例1:输入
(1, 0),距离的平方是1,在第一个环内,因此得分是10。 - 样例2:输入
(1, 1),距离的平方是2,落在第二个环内,因此得分是9。 - 样例3:输入
(0, 5),距离的平方是25,落在第六个环内,因此得分是6。 - 样例4:输入
(3, 4),距离的平方是25,同样落在第六个环内,因此得分是6。
总结
本题的核心在于如何高效地计算射击点的得分。通过计算距离的平方并与预设的阈值进行比较,能够快速确定射击点所在的环,并返回相应的得分。通过这种方法,我们避免了不必要的浮动运算,提高了计算效率。