_1002

    문제 출처: https://www.acmicpc.net/problem/1002

     

    1002번: 터렛

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

    www.acmicpc.net

    케이스는 총 5가지로, 그 중 3개를 그리면 아래와 같다.

     

    [1]번 터렛의 류재명까지의 거리는 ro이고, 문제에서 주어진 r1과 같다. 이 범위를 그리면 원이 나온다. 원을 사용하는 이유는, 저 원이 [1]번 터렛의 정보로만 알 수 있는 류재명이 있을 경우의 수를 모아둔 집합이기 때문이다. 같은 논리로 [2]번 터렛에서의 거리는 rt이고, 문제에서 주어진 r2와 같다. 두 집합을 교집합 시키면 3가지 경우가 나오는데, 수학 관련 과목에서 배웠듯이 원의 접합 경우를 생각하면 3가지가 나온다. 

     

    그 외에, 터렛의 위치가 같을 경우 (x1 == x2, y1 == y2) r1과 r2가 같다면 둘의 터렛 위치가 같으므로 무한한 경우가 나온다. 이 경우 return -1로 처리해둔다. 그 외에 r1와 r2가 같지 않다면 류재명이 없는 경우다. 류재명이 두 명일 수는 없기 때문에, 같은 지점에서 다른 거리 두 곳을 스캔하는데 둘 다 나올 수는 없기 때문에 0명 이다.

     

    따라서 코드를 짜려면 위의 5가지 경우를 고려하는 함수를 만들어주면 된다.

     

    #include <iostream>
    #include <math.h>
    
    using namespace std;
    
    double disCal(int xo, int xt, int yo, int yt) {
    	return double(sqrt(pow(xo - xt, 2) + pow(yo - yt, 2)));
    }
    
    int disRyu(int xo, int yo, int ro, int xt, int yt, int rt) {
    
    	double rl = disCal(xo, xt, yo, yt);
    
    	if (xo == xt && yo == yt) {
    		if (ro == rt) return -1; // 무한 경우
    		if (ro != rt) return 0; // 없는 경우
    	}
    	else if (rl < ro + rt && rl > abs(ro - rt)) {
    		return 2; // 두 가지 경우
    	}
    	else if (rl == ro + rt || rl == abs(ro - rt)) {
    		return 1; // 한 가지 경우
    	}
    	else if (rl > ro + rt) {
    		return 0; // 없음
    	} // 또는 else 로 처리해도 무방
    }
    
    int main() {
    
    	int T;
    	int xo, yo, ro, xt, yt, rt;
    
    	cin >> T;
    
    	for (int i = 0; i < T; i++) {
    		cin >> xo >> yo >> ro >> xt >> yt >> rt;
    		cout << disRyu(xo, yo, ro, xt, yt, rt) <<endl;
    	}
    
    }

     

     

     

     

     

    '백준 풀이' 카테고리의 다른 글

    DP_2748  (0) 2020.08.15
    while_10951  (0) 2020.08.14
    _10871  (0) 2020.08.11
    Brute Force_1436  (0) 2020.08.11
    _2775  (0) 2020.08.10

    댓글