일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 |
30 | 31 |
- Image Classification
- 자료구조
- 사칙연산
- SQL
- 정렬
- 프로그래머스코딩테스트
- 다이나믹프로그래밍
- 수학
- 이진탐색
- 문자열
- 구현
- C언어
- C++
- 백준
- 해시를사용한집합과맵
- C
- 논문구현
- 정수론
- 브루트포스알고리즘
- 백준알고리즘
- 프로그래머스연습문제
- 그리디
- MySQL
- 프로그래머스
- 그리디알고리즘
- 이분탐색
- 소수판정
- 논문리뷰
- 프로그래머스sql
- 큐
- Today
- Total
초보 개발자의 이야기, 릿허브
[C] 백준 1002번 터렛 본문
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인 원이며,
상대편인 류재명이 있을 수 있는 위치는 두 원의 교점과 같다.
원의 교점의 개수는 두 원의 위치관계에 따라 달라지는데,
두 원이 가질 수 있는 위치 관계는 다음과 같다.
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)를 구해준다.
생각보다 수학적인 원리만 알면 간단히 구현할 수 있는 문제였던 것 같다.
다른 문제들은 물론 더 어렵겠지만..
처음 시작했을 때보다는 조금 더 늘지 않았나 하는 생각이 들어서 뿌듯하다.😊
'코딩테스트 > 📗 백준 (BOJ)' 카테고리의 다른 글
[C] 백준 1920번 수 찾기 (0) | 2021.08.04 |
---|---|
[C] 백준 1978번 소수 찾기 (0) | 2021.08.03 |
[C++] 백준 1417번 국회의원 선거 (0) | 2021.08.02 |
[C++] 백준 10814번 나이순 정렬 (0) | 2021.07.30 |
[C++] 백준 9237번 이장님 초대 (0) | 2021.07.29 |