[BOJ] 기하 1 (2)

Wonjun·2022년 9월 2일
0

BOJ

목록 보기
12/16
post-thumbnail

📝3053번: 택시 기하학

문제 설명

택시 기하학

해결 방법

택시 기하학에서 원의 정의에 부합하는 넓이는 마름모의 넓이와 같다. PI 값을 최대한 자세하게 작성하여 소수점 6번째 자리까지 출력한다. C언어 스타일로 출력을 했는데 cout.precision(6)이라는 코드를 활용해도 된다.

💻소스코드

#include <iostream>
#include <stdio.h>

using namespace std;

int main()
{
    // 택시기하학

    int R;  // 반지름
    double u_area, t_area;  // 유클리드 기하학에서 원의 넓이, 택시 기하학에서 원의 넓이
    const double PI = 3.1415926535897932;

    cin >> R;
    u_area = R * R * PI;
    printf("%.6f\n", u_area);
    
    t_area = (2 * R) * (2 * R) / 2;     // 마름모의 넓이
    printf("%.6f\n", t_area);

	return 0;
}

📝1002: 터렛

문제 설명

터렛

해결 방법

두 원의 교점의 개수를 구하는 문제로 재정의할 수 있다.
두 원의 교점의 개수는 두 원의 반지름r1, r2과 두 원의 중심 사이의 거리distance를 알면 알 수 있다.
2차원 좌표평면에서 두 원의 위치관계는 5가지를 생각해볼 수 있다.
1. 원이 외접하는 경우, 1개의 접점이 생긴다.
2. 원이 내접하는 경우, 1개의 접점이 생긴다.
3. 반지름이 작은 원이 큰 원 안에서 만나지 않는 경우, 교점이 없다.
4. 두 원이 멀리떨어져서 만나지 않는 경우, 교점이 없다.
5. 두 원이 두 점에서 만나는 경우, 교점은 2개다.
예외 케이스로 두 원이 일치하는 경우(중심과 반지름이 모두 같다) -1 을 출력한다.
그림으로 그려보면 중심 사이의 거리와 반지름의 관계에 대해서 이해하기 쉽다.

💻소스코드

#include <iostream>
#include <cmath>

using namespace std;

// 두 점 사이의 거리
double dist(double x1, double y1, double x2, double y2) {
    return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
}

int main(void)
{
    // 터렛
    ios_base :: sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);

    int T;
    int x1, y1, r1, x2, y2, r2;

    cin >> T;
    for (int i = 0; i < T; i++) {
        cin >> x1 >> y1 >> r1 >> x2 >> y2 >> r2;
        double distance = dist(x1, y1, x2, y2);
        // 두 원이 겹치는 경우
        if (distance == 0 && r1 == r2)
            cout << "-1\n";
        // 원이 외접하는 경우, 원이 내접하는 경우
        else if (r1 + r2 == distance || abs(r1 - r2) == distance)
            cout << "1\n";
        else if (distance < abs(r1 - r2))  // 작은 원이 큰 원 안에서 만나지 않는 경우
            cout << "0\n";
        else if (distance < r1 + r2)  // 두 원이 두 점에서 만나는 경우
            cout << "2\n";
        else if (distance > r1 + r2)
            cout << "0\n";  // 작은 원이 큰 원 밖에서 만나지 않는 경우
    }

    return 0;
}

📝1004번: 어린왕자

문제 설명

어린왕자

해결 방법

출발점과 도착점을 포함하는 원의 개수를 출력하는 문제로 재정의할 수 있다.
점과 원의 중심 사이의 거리를 구해서 해당 원의 반지름보다 작으면 점이 원의 내부에 있는 것이다. 다만, 출발점과 도착점을 동시에 포함하는 원이 테스트 케이스에 있을 수 있으므로 출발점을 포함하되 도착점을 포함하지 않는 원과 도착점을 포함하되 출발점을 포함하지 않는 원의 개수를 세야 한다.

💻소스코드

#include <iostream>
#include <cmath>

using namespace std;

// 두 점 사이의 거리
double dist(double x1, double y1, double x2, double y2) {
    return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
}

int main()
{
    // 어린 왕자
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);

    int T, n;   // 테스트 케이스 수, 행성계의 개수
    int x1, y1, x2, y2;     // 출발점과 도착점
    int Cx, Cy, r;  // 중점과 반지름

    cin >> T;
    for (int i = 0; i < T; i++) {
        cin >> x1 >> y1 >> x2 >> y2;
        cin >> n;
        int ans = 0;
        for (int j = 0; j < n; j++) {
            cin >> Cx >> Cy >> r;
            if (dist(x1, y1, Cx, Cy) < r)
                if (dist(x2, y2, Cx, Cy) > r)
                    ans++;
            if (dist(x2, y2, Cx, Cy) < r)
                if (dist(x1, y1, Cx, Cy) > r)
                    ans++;
        }
        cout << ans << "\n";
    }

    return 0;
}

📝1358번: 하키

문제 설명

하키

해결 방법

입력으로 선수의 좌표와 하키링크가 주어질 때 하키링크 안에 있거나 경계에 있는 선수의 수를 구하는 문제다.
하키링크는 하나의 직사각형과 양쪽에 반원이 붙어있는 형태다.
선수의 좌표를 입력받아서 좌표가 하키링크 안쪽 또는 경계에 있으면 된다.
직사각형 안에 있으려면 선수의 좌표가 직사각형 꼭짓점의 범위에 있어야 하고, 반원 안에 있으려면 선수 좌표와 반원의 중심 사이의 거리를 구하고, 반원의 반지름과 비교해서 작아야 한다.

💻소스코드

#include <iostream>
#include <cmath>

using namespace std;

// 두 점 사이의 거리
double dist(double x1, double y1, double x2, double y2) {
    return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
}

int main()
{
    // 하키
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);

    int W, H, X, Y, P;
    int x, y;   // 선수 좌표
    int ans = 0;

    cin >> W >> H >> X >> Y >> P;
    for (int i = 0; i < P; i++) {
        cin >> x >> y;
        if (x >= X && x <= X + W && y >= Y && y <= Y + H) // square 안, 또는 경계에 있으면
            ans++;
        else if (dist(x, y, X, Y + H / 2) <= H / 2 || dist(x, y, X + W, Y + H / 2) <= H / 2)   // 반원 안, 또는 경계에 있으면
            ans++;
    }

    cout << ans << "\n";

    return 0;
}

profile
성장 = 학습 + 적용 + 회고

0개의 댓글