Algorithm/기타

[백준 1002번] 터렛

agility 2019. 11. 27. 22:22

백준알고리즘 1002번 : 터렛

 

어릴적에 배웠던 두 원의 교점의 갯수를 구하는 공식을 이용하면 되겠다.

조건문 역시 공식의 조건을 따라서 진행하면 된다.

물론 이 문제에도 함정은 있다..

 

 

풀이 과정

 



1. 두 원의 중심사이의 거리(d)와 각각의 반지름(r1, r2)간의 상관관계에 맞춘 조건을 선정한다.
    ㄱ. 두 원이 두 점에서 만나는 경우( r1 - r2 < d < r1 + r2 ) ▶ 2개
    ㄴ. 두 원이 내접하는 경우( d < r1 -  r2, d!=0 ) ▶ 1개
    ㄷ. 두 원이 외접하는 경우( d < r1 + r2 ) ▶ 1개
    ㄹ. 두 원이 완전히 일치하는 경우( r1 = r2 , d =0 ) ▶ 무한대(-1 출력)
    ㅁ. 두 원의 거리가 멀어 만나지 않는 경우 ( r1 + r2 > d ) ▶ 0개

    ㅂ. 한 원이 다른 원을 포함하여 만나지 않는 경우 ( r1 - r2 < d ) ▶ 0개

2.  해당 조건들에 맞춰 코드를 짠다.

 

 

 

<< 백준알고리즘 1002번 반례 >>

보통은 if else문을 이용하여 2개와 1개, 0개가 나오는 조건을 설정한 뒤, 마지막 else문을 통해 -1을 출력하려 하지 않을까.
나 역시 그렇게 했었으나 에러가 한 번 났었다.

 그 이유는, 두 원이 내접하는 경우(ㄴ)에서 d가 0일 때 else if문에 걸려서 1을 출력해버리기 때문. 문제에서는 r1과 r2에 대해서만 자연수라는 조건을 걸었기 때문에, 1과 r2가 일치하여 r1-r2=d=0이 되버리면 접점이 무한대가 되버린다.

 

 

 

 

소스 ▽

더보기
import java.util.Scanner;

public class Main {// 1002번, 터렛

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int testCase = sc.nextInt();
		int [] ans = new int [testCase];
		
		for (int i = 0; i < testCase; i++) {
			int x1 = sc.nextInt();
			int x2 = sc.nextInt();
			int r1 = sc.nextInt();
			int y1 = sc.nextInt();
			int y2 = sc.nextInt();
			int r2 = sc.nextInt();
			
			int manDistanceSrd = (y1-x1)*(y1-x1)+(y2-x2)*(y2-x2);//원의 중심간의 거리 d의 제곱
			int enemyDistanceP = (r1+r2)*(r1+r2);// 반지름 간의 합의 제곱
			int enemyDistanceM = (r1-r2)*(r1-r2);// 반지름 간의 차의 제곱
			
			if (enemyDistanceP>manDistanceSrd && enemyDistanceM<manDistanceSrd) {
				System.out.println("2");
			}else if (enemyDistanceP==manDistanceSrd || (enemyDistanceM==manDistanceSrd) && manDistanceSrd!=0) {
				System.out.println("1");
			}else if (enemyDistanceP<manDistanceSrd || enemyDistanceM>manDistanceSrd) {
				System.out.println("0");
			}else {
				System.out.println("-1");
			}
			
		}
		
	}
}