알고리즘/문제 풀이

1004: 어린 왕자

Themion 2021. 12. 4. 03:03

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

 

1004번: 어린 왕자

입력의 첫 줄에는 테스트 케이스의 개수 T가 주어진다. 그 다음 줄부터 각각의 테스트케이스에 대해 첫째 줄에 출발점 (x1, y1)과 도착점 (x2, y2)이 주어진다. 두 번째 줄에는 행성계의 개수 n이 주

www.acmicpc.net

시작점과 끝점이 행성계의 경계의 반대편에 있다면 그 행성계의 경계를 반드시 한 번은 통과해야 하고, 이를 확인하려면 시작점과 끝점이 동시에 한 행성계의 안에 있는지를 확인하면 된다.

이 단계를 모든 행성계에 대해 반복하게 되면 시작점에서 끝점까지 이동할 때 최소의 행성계 통과 횟수를 얻을 수 있다.

#include <cstdio>

int sq(int s) { return s * s; }

int test_case() {
    // ss: 각 행성계에 대해 시작점이 행성계 안에 있을 경우 true, 아니라면 false
    // ee: 각 행성계에 대해 끝점이  행성계 안에 있을 경우 true, 아니라면 false
    bool ss, ee;
    // s: 시작점의 좌표, e: 도착점의 좌표
    // p: p[0], p[1]: 각 행성계의 중심의 좌표, p[2]: 행성계의 반지름
    // cnt: 주어진 행성계의 수, ret: 최소 행성계 통과 횟수
    int s[2], e[2], p[3], cnt, ret = 0;

    // 시작점과 끝점의 좌표, 그리고 행성계의 수를 입력받는다
    scanf("%d %d %d %d\n%d", &s[0], &s[1], &e[0], &e[1], &cnt);

    // 각 행성계에 대해
    while (cnt--) {
        // 행성계의 중심의 좌표와 반지름을 입력받은 뒤
        scanf("%d %d %d", &p[0], &p[1], &p[2]);

        // 시작점과 끝점이 행성계 안에 존재하는지 판정한다
        ss = sq(s[0] - p[0]) + sq(s[1] - p[1]) < sq(p[2]);
        ee = sq(e[0] - p[0]) + sq(e[1] - p[1]) < sq(p[2]);

        // 시작점과 끝점이 행성계의 경계에 대해 서로 반대편에 위치한다면
        // 시작점에서 끝점으로 가기 위해 행성계의 경계를 한번 통과해야 한다
        ret += ss != ee;
    }

    // 최소 행성계 통과 횟수를 반환한다
    return ret;
}

int main() {
    int T;

    // 테스트 케이스의 수를 입력받은 뒤
    scanf("%d", &T);
    // 각 테스트 케이스를 실행한다
    while (T--) printf("%d\n", test_case());

    return 0;
}

'알고리즘 > 문제 풀이' 카테고리의 다른 글

1008번: A/B  (0) 2021.12.05
1005번: ACM Craft  (0) 2021.12.05
1003번: 피보나치 함수  (0) 2021.12.04
1002번: 터렛  (0) 2021.12.04
1001번: A-B  (0) 2021.12.03