ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [백준/BOJ] 1002번 : 터렛 (JAVA / 자바)
    백준 2022. 2. 21. 21:14

    안녕하세요~ 코딩하는 코알못 코메인입니다.

     

     

    https://www.acmicpc.net/problem/1002

     

    1002번: 터렛

    각 테스트 케이스마다 류재명이 있을 수 있는 위치의 수를 출력한다. 만약 류재명이 있을 수 있는 위치의 개수가 무한대일 경우에는 -1을 출력한다.

    www.acmicpc.net


    - 문제 -

     

    난이도 실버 4 문제이다.

    자바에서 입력방식은 scanner와 bufferedreader가 있다.

    자바를 초반에 접하면 처음에 배우는 입력은 scanner이다. scanner가 bufferedreader보다 편하지만 속도가 느리다.

    bufferedreader는 무조건 문자열로 받아오기때문에 정수형이나 실수형 변수에 저장하기 위해서는 입력과 형변환을 해줘야한다.

    더 자세한 내용은 아래 글 참고 하면 좋다.

    https://comain.tistory.com/3

     

    (JAVA / 자바) Scanner 와 Bufferedreader

    안녕하세요~ 코딩하는 코알못 코메인입니다. 이번엔 백준 문제 풀면서 계속 언급될 scanner와 bufferedreader에 대한 간단한 정리를 해볼거다. 자바에서 입력은 scanner와 bufferedreader가 있다. 우선 각자

    comain.tistory.com

     

    풀이 방법

    원으로 생각하면 편하다. 조씨와 백씨의 각 자신의 좌표를 기준으로 마린까지의 거리만큼의 반지름을 가지는 원을 그렸을때 두 원의 접점이 개수를 구하면 된다.

    두 원이 그려지는 경우는 총 6가지가 있다.

    1. 한 원이 다른 한 원의 안에 있지 않을때 닿지 않으면 접점이 없기때문에 0이 된다.

    2. 한 원이 다른 한 원의 안에 있을때 닿지 않게 있으면 접점이 없기때문에 0이 된다.

    3. 한 원이 다른 한 원의 안에 있지 않을때 원의 한 점만 닿게 되면 접점이 한개이기 때문에 1이 된다.

    4. 한 원이 다른 한 원의 안에 있을때 원의 한 점만 닿게 되면 접점이 한개이기 때문에 1이 된다.

    5. 한 원이 다른 한 원의 안에 있지 않을때 원의 두 점이 닿게 되면 접점이 두개이기 때문에 2이 된다.

    6. 남은건 무한대인데 무한대려면 원과 원의 완전 겹쳐야 한다. 그렇기때문에 두 원의 중점의 좌표와 거리가 같이야 한다. 그렇데하면 -1이 된다.

     

    이렇게 총 6가지가 나오는데 두 원이 한 원과 다른 원이 안에 있을때 밖에 있을때, 닿는 점은 몇개인지를 판단하기 위해서는 두 사람의 거리와, 마린까지의 거리의 상관관계를 보면된다.

     

    두 사람의 거리는 ((x2 - x1)^2 + (y2 - y1)^2)루트 이다. 마린까지의 거리는 ㅣr2 - r1ㅣ , ㅣr2 + r1ㅣ 두가지의 경우로 원의 포함관계를 본다. 예를 들어 ((x2 - x1)^2 + (y2 - y1)^2)루트 > ㅣr2 + r1ㅣ이런 값이 나오게 된다면 이것은 각 원은 밖에 있으며, 서로 접점이 없다는 것이다. 하지만 저렇게 되면 루트를 통해 실수가 나올텐데, 실수는 괜히 걸리는게 있을 수 있기 때문에 그냥 (x2 - x1)^2 + (y2 - y1)^2 > (r2 + r1)^2 이렇게 루트를 하지않고 마린과의 거리쪽을 제곱해줄 것이다. 위에 접점을 보기위한 식을 보자면.

    1. (x2 - x1)^2 + (y2 - y1)^2 > (r2 + r1)^2

    2. (x2 - x1)^2 + (y2 - y1)^2 < (r2 - r1)^2

    3. (x2 - x1)^2 + (y2 - y1)^2 = (r2 + r1)^2

    4. (x2 - x1)^2 + (y2 - y1)^2 = (r2 - r1)^2

    5. (x2 - x1)^2 + (y2 - y1)^2 < (r2 + r1)^2

    6. x1 = x2 and y1 = y2 and r1 = r2

    가 된다. 이중 하나는 굳이 조건으로 쓰지 않고 다른 5가지 조건에 충족되지 않을때 나오게 할 것이다.(필자는 5번째 식을 선택했다.)

    여기서 주의할 점은 6번째에 적었지만 무한대가 조건문 맨 처음에 와야한다. 이유는 5 5 5 5 5 5가 되면 4번이나, 3번에도 해당되어지기 때문이다.

    코드로 보자.


    -풀이-

     

    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.util.StringTokenizer;
    
    public class Main {
    	
    	public static void main(String[] args) throws IOException {
    		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    		int T = Integer.parseInt(br.readLine());
    		
    		for(int i = 0; i < T; i++) {
    			StringTokenizer st = new StringTokenizer(br.readLine());
    			int x1 = Integer.parseInt(st.nextToken());
    			int y1 = Integer.parseInt(st.nextToken());
    			int r1 = Integer.parseInt(st.nextToken());
    			int x2 = Integer.parseInt(st.nextToken());
    			int y2 = Integer.parseInt(st.nextToken());
    			int r2 = Integer.parseInt(st.nextToken());
    			
    			//1조건을 빼고 공통적으로 들어가는 조건이기때문에 변수에 저장해서 사용
    			int distance = (int) (Math.pow((x2 - x1), 2) + Math.pow((y2 - y1), 2));
    			
    			if(x1 == x2 && y1 == y2 && r1 == r2) System.out.println(-1);
    			
    			else if(distance > Math.pow((r2 + r1), 2)) System.out.println(0);
    			
    			else if(distance < Math.pow((r2 - r1), 2)) System.out.println(0);
    			
    			else if(distance == Math.pow((r2 + r1), 2)) System.out.println(1);
    			
    			else if(distance == Math.pow((r2 - r1), 2)) System.out.println(1);
    		
    			else System.out.println(2);
    		}
    	}
    
    }

    -결과-

     

    문제 자체는 이해하는데 어렵진 않았으나 구현 방법, 원을 이용한다는 방식을 생각하는데 오래 걸렸다.

    막상 풀면 어렵진 않았다.


    아직 코딩 공부가 부족한 필자라 설명과 풀이 방법이 많이 미흡할 수 있다. 코딩 고수분들은 보시고 문제점이 있다면 댓글로 말해주시면 감사한 마음으로 참고 수정 하겠습니다.

    댓글