Baekjoon algorithm training

[백준] 1002 (터렛)

interfacer_han 2023. 10. 25. 14:24

#1 알고리즘

#1-1

 

#1-2

 

#1-3

 

#2 코드

#2-1 자바

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String loopCountStr = sc.nextLine().trim(); // trim()으로 앞 뒤 공백과 줄바꿈 기호 제거
        int loopCount = Integer.parseInt(loopCountStr); 

        for(int i = 0; i < loopCount; i++) {
            String testCase = sc.nextLine().trim(); 
            
            String[] testCaseValues = testCase.split(" ");
            int x1 = Integer.parseInt(testCaseValues[0]);
            int y1 = Integer.parseInt(testCaseValues[1]);
            int r1 = Integer.parseInt(testCaseValues[2]);
            int x2 = Integer.parseInt(testCaseValues[3]);
            int y2 = Integer.parseInt(testCaseValues[4]);
            int r2 = Integer.parseInt(testCaseValues[5]);
            
            int pointOfContact = pointOfContactCalculation(x1, y1, r1, x2, y2, r2);
            System.out.println(Integer.toString(pointOfContact));
        }

        sc.close();
    }
    
    public static int pointOfContactCalculation(int x1, int y1, int r1, int x2, int y2, int r2) {
        // The square of the distance between two centers
        int centerDistanceSq = (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2);
        // Absolute difference of radiuses
        int radiusAbsDiffSq = (r1 - r2) * (r1 - r2); 
        int radiusSumSq = (r1 + r2) * (r1 + r2);
        
        if(centerDistanceSq == 0 && r1 == r2) {
            return -1;
        }
        
        if(radiusAbsDiffSq < centerDistanceSq) {
            if(radiusSumSq < centerDistanceSq) {
                return 0;
            }
        
            if(radiusSumSq == centerDistanceSq) {
                return 1;
            }

            return 2; // radiusSumSq > centerDistanceSq
            
        } else if(radiusAbsDiffSq == centerDistanceSq) {
            return 1;

        } else { // radiusAbsDiffSq > centerDistanceSq
            return 0; 
        }
    }
}

함수 pointOfContactCalculation에서 centerDistanceSq, radiusAbsDiffSq, radiusSumSq에 제곱근을 취해 centerDistance, radiusAbsDiff, radiusSum와 같은 식으로 사용하지 않는 이유는 2가지가 있다,
첫째는, 크기 비교라서 굳이 제곱근을 취하지 않아도 동일한 결과가 나오기 때문이다. 문제에서 x1, y1, r1, x2, y2, r2의 값은 정수라는 조건이 있다. 따라서, 제곱근을 취하지 않는 이상 int형만으로도 계산이 가능하다.
둘째는, 자바에서 제곱근을 구할 때 사용하는 Math.sqrt() 함수는 double형을 반환하기 때문이다. double형은 부동소수점 방식인데, 소수점 아래 부분에서 부정확한 결과가 나올 여지가 있다. 

 

#2-2 코틀린

fun main() {
    val loopCount = readLine()!!.trim().toInt()
    
    for(i : Int in 1..loopCount) {
        val testCase = readLine()!!.trim()
        val testCaseValues = testCase.split(" ")
        
        val x1 = testCaseValues[0].toInt()
        val y1 = testCaseValues[1].toInt()
        val r1 = testCaseValues[2].toInt()
        val x2 = testCaseValues[3].toInt()
        val y2 = testCaseValues[4].toInt()
        val r2 = testCaseValues[5].toInt()
        
        val pointOfContact = pointOfContactCalculation(x1, y1, r1, x2, y2, r2)
        println(pointOfContact.toString())
    }
}

fun pointOfContactCalculation(x1 : Int, y1 : Int, r1 : Int, x2 : Int, y2 : Int, r2 : Int) : Int {
    val centerDistanceSq = (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)
    val radiusAbsDiffSq = (r1 - r2) * (r1 - r2)
    val radiusSumSq = (r1 + r2) * (r1 + r2)
    
    if(centerDistanceSq == 0 && r1 == r2) {
        return -1
    }
        
    if(radiusAbsDiffSq < centerDistanceSq) {
        if(radiusSumSq < centerDistanceSq) {
            return 0
        }
        
        if(radiusSumSq == centerDistanceSq) {
            return 1
        }

        return 2 // radiusSumSq > centerDistanceSq
            
    } else if(radiusAbsDiffSq == centerDistanceSq) {
        return 1

    } else { // radiusAbsDiffSq > centerDistanceSq
        return 0
    }
}