-
[백준/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는 무조건 문자열로 받아오기때문에 정수형이나 실수형 변수에 저장하기 위해서는 입력과 형변환을 해줘야한다.
더 자세한 내용은 아래 글 참고 하면 좋다.
(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); } } }
-결과-
문제 자체는 이해하는데 어렵진 않았으나 구현 방법, 원을 이용한다는 방식을 생각하는데 오래 걸렸다.
막상 풀면 어렵진 않았다.
아직 코딩 공부가 부족한 필자라 설명과 풀이 방법이 많이 미흡할 수 있다. 코딩 고수분들은 보시고 문제점이 있다면 댓글로 말해주시면 감사한 마음으로 참고 수정 하겠습니다.
'백준' 카테고리의 다른 글
[백준/BOJ] 1003번 : 피보나치 함수 (JAVA / 자바) (0) 2022.02.22 [백준/BOJ] 1021번 : 회전하는 큐 (JAVA / 자바) (0) 2022.02.21 [백준/BOJ] 1181번 : 단어 정렬 (JAVA / 자바) (2) 2022.02.20 [백준/BOJ] 1158번 : 요세푸스 문제 (JAVA / 자바) (0) 2022.02.20 [백준/BOJ] 1094번 : 막대기 (JAVA / 자바) (0) 2022.02.20