문제 출처: 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 |
댓글