초보 개발자의 이야기, 릿허브

[C] 백준 1002번 터렛 본문

코딩테스트/📗 백준 (BOJ)

[C] 백준 1002번 터렛

릿99 2021. 8. 3. 09:15
728x90
반응형
1. 문제이해

https://www.acmicpc.net/problem/1002

 

1002번: 터렛

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

www.acmicpc.net

 

조규현과 백승현의 좌표(각각 (x1, y1), (x2, y2))가 주어지고, 상대편인 류재명과의 거리(r1, r2)가 주어질 때,

류재명이 있을 수 있는 좌표의 갯수를 출력하는 알고리즘을 구현하는 것이 목표이다.

 

 

 

2. 문제풀이

 

두 원의 교점의 갯수를 구하는 알고리즘이다.

조규현, 백승현은 각각 중심이 (x1, y1), (x2, y2), 반지름이 r1, r2인 원이며,

상대편인 류재명이 있을 수 있는 위치는 두 원의 교점과 같다.

 

원의 교점의 개수는 두 원의 위치관계에 따라 달라지는데,

두 원이 가질 수 있는 위치 관계는 다음과 같다.

 

출처 : https://mathjk.tistory.com/178

 

1. 두 원의 교점이 무한개

: 두 원이 일치하는 경우이므로, 두 원의 중심과 반지름이 일치하는지를 체크해 주면 된다.

문제의 조건에 따라 -1을 출력한다.

 

2. 두 원의 교점이 2개

: 위 그림에서 두 점에서 만나는 경우에 해당하며,

두 원의 중심사이의 거리가 두 원의 반지름의 차보다 크고 합보다는 작아야 한다.

 

3. 두 원의 교점이 1개

: 위 그림에서 한 점에서 만나는 경우(접하는 경우)에 해당하며,

외접하는 경우에는 두 원의 중심사이의 거리가 두 원의 반지름의 합이어야 하고,

내접하는 경우에는 두 원의 중심사이의 거리가 두 원의 반지름의 차와 같아야 한다.

 

4. 두 원의 교점이 0개

: 위 그림에서 만나지 않는 경우에 해당하며,

외부에서 만나지 않는 경우, 내부에 포함되는 경우, 동심원인 경우 등이 있으며

코드로 구현했을 때 else문을 이용하여 따로 조건을 입력하지 않고 처리해주었다.

 

 

 

3. 소스코드
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <math.h>

int main() {
	int testcase;
	int x1, y1, r1, x2, y2, r2;
	int i = 0;
	int intersection_point = 0;

	scanf("%d", &testcase);	// 테스트케이스의 갯수 입력

	for (i; i < testcase; i++) {
		scanf("%d %d %d %d %d %d", &x1, &y1, &r1, &x2, &y2, &r2);
		int sum = r1 + r2;	// 두 원의 반지름의 합
		int difference = abs(r1 - r2);	// 두 원의 반지름의 차
		// 두 원의 중심 사이의 거리
		double distance = sqrt(pow((x1 - x2), 2) + pow((y1 - y2), 2));	

		// 1. 두 원이 일치하는 경우 (교점이 무한개)
		if (distance == 0 && r1 == r2) {	
			intersection_point = -1;
		}
		// 2. 두 원이 외접하거나 내접하는 경우 (교점이 1개)
		else if (distance == sum || distance == difference) {
			intersection_point = 1;
		}
		// 3. 두 원이 두점에서 만나는 경우  (교점이 2개)
		else if (difference < distance && distance < sum) {
			intersection_point = 2;
		}
		// 4. 두 원이 만나지 않는 경우 (교점이 0개)
		else 
			intersection_point = 0;

		printf("%d\n", intersection_point);
	}

	return 0;
}

먼저, 테스트케이스의 갯수를 입력받는다.

그리고 각 테스트케이스마다 조규현과 백승현의 중심좌표, 반지름을 입력받는다.

입력받은 값을 이용해, 두 원의 반지름의 합(sum), 차(difference),

두 원의 중심 사이의 거리(distance)를 계산한다.

 

이후에는 2. 문제풀이에서 도출한 경우에 따라

if, else 문을 이용하여 교점의 갯수(intersection_point)를 구해준다.

 

 


 

생각보다 수학적인 원리만 알면 간단히 구현할 수 있는 문제였던 것 같다.

다른 문제들은 물론 더 어렵겠지만..

처음 시작했을 때보다는 조금 더 늘지 않았나 하는 생각이 들어서 뿌듯하다.😊

 

 

 

 

 

728x90
반응형