본문 바로가기
백준

[백준] 단계별로 풀어보기(단계:9,기본수학2,JAVA)1002번, 터렛

by 열정적인 이찬형 2022. 1. 6.

문제 링크

1002번: 터렛
 
www.acmicpc.net

주의사항

  • JAVA를 사용하여 프로그램을 사용하였습니다.
  • 백준에서 코드를 작성하였을 때 아래 형태에서 Main에서 결과가 출력되어야 합니다.
public class Main{ 	
	public static void main(String[] args){
    }
}

문제 설명


접근 방법

처음 문제를 읽었을 때 내용이 생각보다 막막해서 어려운 문제인줄 알았지만 해결법을 알게되면서 쉬운 문제임을 알게되었습니다.

좌표에 여러가지 그려보다가 레이더같은 느낌을 떠올려서 좌표를 기준으로 거리만큼 원을 2가지 그려보니 교점이 나오는 것을 알게 되었으며 이것이 문제를 푸는데 핵심적인 내용이라는 것을 깨닫고 사용하였습니다.

결과가 0이 나오면 교점이 없는 것이며 1이 나오면 교접이 1개, 2가 나오면 교점이 2개라는 것을 알게되었습니다.

교점이 2개 일 때(예제 입력 1번)

|r₁ - r₂| < d < r₁ + r₂

 

교점이 1개일 때

r₁ + r₂ == d

|r₁ - r₂| == d

교점 0개일 때

r₁ + r₂ < d

|r₁ - r₂| > d

d == 0  && r₁ != r₂

교점이 무수히 많을 때

d == 0  && r₁ == r₂

 

검은색으로 그려진 마름모 형태가 택시기하학에서의 원의 표시입니다.

파란색으로 그려진 것을 살펴보면 택시기하학에서는 대각선으로 이동하지 못하기 때문에 한 블록씩 이동하며 반지름이 3이기 때문에 파란색처럼 이동하여 도착하는 지점이 마름모 형태로 만들어질 수 있습니다.

그래서 마름모 공식인 한 대각선 × 다른 대각선 ÷ 2 를 구하면 택시기하학에서 나타내는 원의 넓이를 구할 수 있습니다.

문제에서는 반지름이 주어지기 때문에 공식을(r×2)² ÷ 2 로 구하면 됩니다.

그럼 코드를 살펴보도록 하겠습니다.

 

  • BufferedReader를 사용하여 입력 값을 받았습니다.
  • StringTokenizer를 통해서 띄어쓰기 기준으로 나누었습니다.
  • 교점의 개수를 구하는 IntersectionPoint함수를 만들었습니다.
  • 좌표 간의 거리는 (x₂-x₁)² + (y₂-y₁)²를 통해서 이용하였습니다.
  • 원래 루트를 씌어야 하지만 double으로 출력되면 복잡해져서 제곱형태로 이용하였습니다.
  • 위에 내용처럼 교점 개수를 구하는 조건에 맞게 결과를 출력하도록 하였습니다.
  • bw에 함수 결과를 저장하였습니다.
  • BufferedWriter를 통해 저장된 결과를 출력하였습니다.

결과 코드

import java.io.*;
import java.util.*;
public class Main{
	public static void main(String[] args) throws IOException{
    	BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        //BufferedReader를 통해 입력 값 받기
    	BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
       	//BufferedWriter를 통해 결과 출력
    	int index = Integer.parseInt(br.readLine());
    	StringTokenizer st;
    	for(int i=0;i<index;i++) {
    		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());
    		int d = (int) (Math.pow(x2-x1, 2) + Math.pow(y2-y1, 2));	//좌표 거리 구하기
    		bw.write(IntersectionPoint(r1, r2, d) + "\n");	//교점 bw에 저장하기
    	}
    	bw.flush();
    	bw.close();
    	br.close();	
	}
	public static String IntersectionPoint(int r1, int r2, int d) {		//교점 확인 함수
		if(d==0 && r1==r2 )	//무수히 많을 때
			return "-1";
		else if(Math.pow(r1+r2, 2)==d || Math.pow(r1-r2,2)==d)	//교점 1개일 때
			return "1";
		else if(Math.pow(r1+r2, 2)<d || Math.pow(r1-r2,2)>d || (d==0 && r1!=r2))//교점0개일 때
			return "0";
		else		//교점 2개일 때
			return "2";
	}
}
 

댓글