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

119 阅读3分钟

这道题的关键在于,根据射击点所处的最小整数半径圆的半径,来决定最终的得分

所以突破口就在于如何求出这个最小圆的半径

我们可以得到这样一个结论:这个最小圆的半径其实就是大于等于射击点到靶心(坐标原点)距离的最小整数

道理很简单,举个例子,比如射击点到靶心的距离为5.5,这个值是在 (5,6] 的范围内,那么我们就会认为射击点至少是在半径为6的圆内,对应的成绩就是5分。射击点到靶心的距离已经超过5了,总没有理由说最终的成绩是6分(对应半径为5的圆)吧,所以这里最小圆的半径必须大于等于射击点到靶心的距离。同时也要满足“最小”的条件,我们不会认为距离5.5对应的最终成绩是4分,因为每一个得分对应一个范围,5分(半径为6的圆环)就是 (5,6],4分(半径为7的圆环)就是 (6,7],落在某个范围就对应某个分数,5.5落在的范围就是 (5,6],对应的分数就是半径为6的圆环的分数,因此5.5对应的最小圆的半径就是6

要求最小圆的半径,首先要求出射击点到靶心的距离,把靶放到坐标系进行分析,我们在数学课里学过,在坐标系中任意一点 (x, y) 到原点的距离可以表示为:

d=x2+y2d = \sqrt{x^2 + y^2}

要进行开方运算,我们可以使用 Java 的 Math 库中的 sqrt 函数:

double d = Math.sqrt(x * x + y * y);

算出射击点到靶心的距离,接下来就要计算射击点所处的最小整数半径圆的半径,也就是大于等于射击点到靶心距离的最小整数,要求出这个数,Java 的 Math 库中同样有很方便的计算方式,也就是 ceil 函数,这个函数可以返回大于等于指定参数的最小整数:

int i = (int)(Math.ceil(d));

由于 ceil 函数的返回值是 double 类型,最终需要的最小圆的半径值为 int 类型,因此这里对函数的返回值做了强制类型转换

接下来,根据题目要求:

若射击点在某个半径为 i 的圆内,则得 11-i 分。如果射击点超出所有的环,则得0分。

我们就能将刚刚算出的最小圆的半径 i 换算成最终得分。当然,这里需要注意,不能直接用 11-i 算出最终得分,因为最小圆的半径 i 有可能大于等于11,也就意味着射击点超出所有的环,所以我们在这里需要做出判断:

if(i <= 10) { return 11 - i; }

若超出所有的环,则不会进入 if 分支,直接执行 return 0 即可

public static int solution(int x, int y) {
        // write code here
        double d = Math.sqrt(x * x + y * y);
        int i = (int)(Math.ceil(d));
        if(i <= 10) {
            return 11 - i;
        }
        return 0;
}