백준 1004

야민·2023년 3월 18일
0

백준

목록 보기
2/8

1004번 "어린 왕자" 문제는 행성계의 중심좌표와 반지름, 그리고 출발점과 도착점이 주어졌을 때, 출발점과 도착점을 지나는 선분이 행성계와 교점을 몇 개 가지는지 구하는 문제입니다.
이 문제는 여러 개의 테스트 케이스가 주어지고, 각각의 테스트 케이스에 대해 출발점과 도착점이 원 안에 있으면서 둘 다 원 밖에 있는 경우, 둘 중 하나만 원 안에 있는 경우, 둘 다 원 안에 있는 경우, 둘 다 원 밖에 있는 경우로 총 네 가지 경우를 구분하여 처리해야 합니다.
이 문제를 해결하기 위해 먼저, 선분과 원의 교점의 개수를 구하는 방법을 알아보겠습니다.
원과 선분의 교점 개수를 구하는 방법은 다음과 같습니다.

선분의 양 끝점이 원 안에 있으면서 선분이 원 안에 있는 경우 : 교점 개수 0개
선분의 양 끝점이 원 밖에 있으면서 선분이 원 밖에 있는 경우 : 교점 개수 0개
선분의 양 끝점이 원 안에 있으면서 선분이 원 밖에 있는 경우 : 교점 개수 2개
선분의 양 끝점이 원 밖에 있으면서 선분이 원 안에 있는 경우 : 교점 개수 2개
선분의 한 끝점이 원 안에 있고, 다른 끝점이 원 밖에 있는 경우 : 교점 개수 1개

#include <iostream>
#include <cmath>
using namespace std;
// 원의 중심과 반지름 정보를 담는 구조체
struct Circle {
    int x;
    int y;
    int r;
};
// 두 점 사이의 거리 계산 함수
double distance(int x1, int y1, int x2, int y2) {
    return sqrt(pow(x2 - x1, 2) + pow(y2 - y1, 2));
}
int main() {
    int T;
    cin >> T;
    while (T--) {
        int x1, y1, x2, y2;
        cin >> x1 >> y1 >> x2 >> y2;
        int n;
        cin >> n;
        int count = 0;
        while (n--) {
            Circle c;
            cin >> c.x >> c.y >> c.r;
            // 출발점과 도착점 중 하나만 포함된 원은 교차하지 않는다
            if (distance(x1, y1, c.x, c.y) < c.r && distance(x2, y2, c.x, c.y) < c.r)
                continue;
            // 출발점과 도착점 모두 원 안에 있으면 교차하지 않는다
            if (distance(x1, y1, c.x, c.y) < c.r && distance(x2, y2, c.x, c.y) < c.r)
                continue;
            // 출발점과 도착점이 원 안에 없으면 교차하지 않는다
            if (distance(x1, y1, c.x, c.y) > c.r && distance(x2, y2, c.x, c.y) > c.r)
                continue;
            // 위의 경우가 모두 아니라면 교차하는 원이다
            count++;
        }
        cout << count << endl;
    }
    return 0;
}

위 코드는 입력받은 출발점과 도착점을 지나는 선분과 각 원들의 교차 여부를 판단하여 문제를 해결하는 방식으로 구현되어 있습니다. 입력 형식에 맞춰 여러번의 테스트 케이스를 처리할 수 있도록 while문을 이용해 반복적으로 입력을 받고, 출력합니다.

0개의 댓글