问题描述
小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解题过程及代码详解
问题理解
小E在射击练习中,靶心位于坐标 (0, 0),靶有10个环,每个环对应不同的得分。靶心内(半径为1)得10分,依次向外的每个环分数减少1分。若射击点在某个半径为 i 的圆内,则得 11-i 分。如果射击点超出所有的环,则得0分。
我们需要根据给定的射击坐标 (x, y) 计算小E的射击得分。
数据结构选择
在这个问题中,我们不需要复杂的数据结构。我们只需要计算射击点到靶心的距离,并根据距离确定得分。
当我不知道一些方法怎么写时?
我会问豆包MarsCode AI,我问他
怎么计算一个数的平方根?
他会告诉我:在Java中,计算一个数的平方根可以使用 Math.sqrt() 方法。这个方法位于 java.lang 包中,因此不需要显式导入。
使用 Math.sqrt() 方法
Math.sqrt() 方法接受一个 double 类型的参数,并返回该参数的平方根。返回值也是一个 double 类型。
算法步骤
-
计算射击点到靶心的距离:
- 使用欧几里得距离公式:
distance = sqrt(x^2 + y^2)。
- 使用欧几里得距离公式:
-
确定得分:
- 如果距离小于等于1,得分是10分。
- 如果距离大于1且小于等于2,得分是9分。
- 以此类推,直到距离大于10,得分是0分。
-
返回得分:
- 根据计算的距离,返回相应的得分。 代码实现
public static int solution(int x, int y) {
// 计算射击点到靶心的距离的平方
int distanceSquared = x * x + y * y;
// 计算距离
double distance = Math.sqrt(distanceSquared);
// 根据距离确定得分
if (distance <= 1) {
return 10;
} else if (distance <= 2) {
return 9;
} else if (distance <= 3) {
return 8;
} else if (distance <= 4) {
return 7;
} else if (distance <= 5) {
return 6;
} else if (distance <= 6) {
return 5;
} else if (distance <= 7) {
return 4;
} else if (distance <= 8) {
return 3;
} else if (distance <= 9) {
return 2;
} else if (distance <= 10) {
return 1;
} else {
return 0;
}
}
public static void main(String[] args) {
// 测试样例
System.out.println(solution(1, 0) == 10); // 应该输出 true
System.out.println(solution(1, 1) == 9); // 应该输出 true
System.out.println(solution(0, 5) == 6); // 应该输出 true
System.out.println(solution(3, 4) == 6); // 应该输出 true
}
}
代码详解
-
计算距离的平方:
int distanceSquared = x * x + y * y;- 这里我们计算了射击点到靶心的距离的平方,避免了直接计算平方根,因为平方根计算相对较慢。
-
计算距离:
double distance = Math.sqrt(distanceSquared);- 这里我们计算了实际的距离,用于后续的得分判断。
-
根据距离确定得分:
- 我们使用一系列的
if-else语句来判断距离,并返回相应的得分。 - 例如,如果距离小于等于1,返回10分;如果距离大于1且小于等于2,返回9分,以此类推。
- 我们使用一系列的
-
测试样例:
- 在
main方法中,我们提供了一些测试样例来验证代码的正确性。 - 每个测试样例都打印出结果,并与预期结果进行比较,确保代码的正确性。
- 在
优化建议
-
减少重复计算:
- 在当前代码中,我们计算了距离的平方和实际距离。实际上,我们可以直接使用距离的平方来进行判断,避免计算平方根。
-
简化判断逻辑:
- 我们可以使用一个循环来简化判断逻辑,而不是使用多个
if-else语句。
- 我们可以使用一个循环来简化判断逻辑,而不是使用多个
优化后的代码如下:
public static int solution(int x, int y) {
// 计算射击点到靶心的距离的平方
int distanceSquared = x * x + y * y;
// 根据距离的平方确定得分
for (int i = 1; i <= 10; i++) {
if (distanceSquared <= i * i) {
return 11 - i;
}
}
// 如果距离大于10,返回0分
return 0;
}
public static void main(String[] args) {
// 测试样例
System.out.println(solution(1, 0) == 10); // 应该输出 true
System.out.println(solution(1, 1) == 9); // 应该输出 true
System.out.println(solution(0, 5) == 6); // 应该输出 true
System.out.println(solution(3, 4) == 6); // 应该输出 true
}
}
优化后的代码详解
-
计算距离的平方:
int distanceSquared = x * x + y * y;- 这里我们仍然计算了射击点到靶心的距离的平方。
-
根据距离的平方确定得分:
- 我们使用一个循环来判断距离的平方是否小于等于某个环的半径的平方。
- 如果满足条件,返回相应的得分。
-
返回0分:
- 如果距离的平方大于100(即距离大于10),返回0分。
通过这种方式,我们减少了重复计算,并且简化了判断逻辑,使代码更加简洁和高效。
总结
通过上述详细的解题过程和代码实现,我们可以看到如何逐步解决这个问题。我们从问题理解开始,选择合适的数据结构和算法,然后实现代码并进行优化。最终,我们得到了一个高效且简洁的解决方案。