프로그래머스 - 두 원 사이의 정수 쌍[Java]

우노구나·2025년 6월 30일

문제설명

반지름을 나타내는 두 정수 r1, r2가 매개변수로 주어질 때, 두 원 사이의 공간에 x좌표와 y좌표가 모두 정수인 점의 개수를 구하는 문제


코드

import java.util.*;

class Solution {
    public long solution(int r1, int r2) {
        long answer = 0;
        
        answer += (long)(r2 - r1 + 1) * 4;
        
        for(int i=1; i<r2; i++){
            
            long tmp1 = (long)Math.pow(r2,2);
            long tmp2 = (long)Math.pow(i,2);
            
            long top = (long)Math.floor(Math.sqrt(tmp1 - tmp2));
            answer += top * 4;
        }
        
        for(int i=1; i<r1; i++){
            long tmp1 = (long)Math.pow(r1,2);
            long tmp2 = (long)Math.pow(i,2);
            
            long top = (long)Math.ceil(Math.sqrt(tmp1 - tmp2)) - 1;
            answer -= top * 4;
        }

        return answer;
    }
}

과정

구현 자체는 어렵지 않았다. 큰 원 안에 있는 정수쌍의 개수에서 작은 원 안에 있는 정수쌍의 개수를 빼면 되는 문제.(15줄로 푼 분도 계시는데 매커니즘 자체는 비슷하다.)

문제는 long 타입을 사용하는거였다. 뒷번호 테스트케이스만 통과되지 않을 때 타입 문제라고 생각을 했는데, 어디서 문제가 발생한건지 찾는게 어려웠다.

문제의 원인은

long tmp1 = r2 * r2;

여기서 발생했다.
int형인 r2를 곱하면 int로 담기에는 오버플로우가 생겨 long타입으로 받으면 괜찮을 줄 알았지만 java에서 int * int 는 int 범위 내에서 계산이 되기 때문에 tmp1으로 넘겨주기 전에 이미 오버플로우가 발생한다....!!

그래서 코드를

long tmp1 = (long)r2 * r2;

또는

long tmp1 = (long)Math.pow(r1,2);

이렇게 바꿔야한다...
(참고로 pow는 결과가 double로 계산된다.)


배운점

항상 long타입이 나올 때 이러한 오버플로우 문제로 어려움을 자주 겪는 것 같다.
int * int는 int 범위에서 계산되는걸 꼭 기억하자....!

profile
기술 블로그

0개의 댓글