좌표평면을 좋아하는 진수는 x축과 y축이 직교하는 2차원 좌표평면에 점을 찍으면서 놀고 있습니다. 진수는 두 양의 정수 k, d가 주어질 때 다음과 같이 점을 찍으려 합니다.
a*k(a = 0, 1, 2, 3 ...), y축 방향으로 b*k(b = 0, 1, 2, 3 ...)만큼 떨어진 위치에 점을 찍습니다.d를 넘는 위치에는 점을 찍지 않습니다.예를 들어, k가 2, d가 4인 경우에는 (0, 0), (0, 2), (0, 4), (2, 0), (2, 2), (4, 0) 위치에 점을 찍어 총 6개의 점을 찍습니다.
정수 k와 원점과의 거리를 나타내는 정수 d가 주어졌을 때, 점이 총 몇 개 찍히는지 return 하는 solution 함수를 완성하세요.
k ≤ 1,000,000d ≤ 1,000,000| k | d | result |
|---|---|---|
| 2 | 4 | 6 |
| 1 | 5 | 26 |
입출력 예 #1
입출력 예 #2
class Solution {
public long solution(int k, int d) {
long answer = 0;
for(int x = 0; x <= d; x += k) {
long dd = (long)d * d;
long xx = (long)x * x;
// 나올 수 있는 y의 최대값
long y = (long)Math.sqrt(dd - xx);
// 범위에 포함되는 y의 개수를 더해줌
answer += y / k + 1;
}
return answer;
}
}
반복문을 사용해서 진행하였다.
반지름이 d인 원 안에 포함되는 1사분면의 점들을 구하는 문제였다. 이때 모든 점이 아닌 k만큼의 거리가 있어야한다.
따라서 반복문을 x = 0부터 진행을 하되, x += k를 사용하였다.
거리를 구하는 공식은 d^2 = x^2 + y^2이다.
이때 y의 값을 구하기 위해선 root(d^2 - x^2)를 해주면 된다.
위의 수식에서 나온 y의 값은 x일 때 나올 수 있는 최대 y의 값이며, 포함되는 모든 y의 개수를 구하기 위해선 y / k + 1을 해주면 된다.
위의 모든 반복을 진행하면서 나온 모든 y / k + 1의 값을 answer에 더해준 뒤 반복문을 빠져나와 answer를 반환해주면 문제를 해결할 수 있다!
문제를 해결하는 코드는 쉽게 짤 수 있었으나, 자료형을 생각하는 부분에서 시간을 조금 썼다. long = int x int를 했을 경우 int x int형에서 범위가 벗어나 오류가 생기는 부분을 그대로 long형에 저장이 되기 때문에 오류가 발생했다. 이 부분을 해결하기 위해서 (long)d x d 등 계산을 따로 해서 저장하고 수식에 대입해서 해결하였다. 간단한 부분이었으나 바로 생각하지 못해서 많은 실패를 하였다.. 조금 더 꼼꼼하게 문제를 풀어야겠다..