본문 바로가기
PS - 알고리즘

2244 - 민코프스키 합

by codeStudyCafe 2025. 1. 20.

step 1

더보기

다각형 A의 원점을 다각형 B의 한 꼭짓점으로 이동시켜 봅시다. 그때, 다각형 A가 차지하는 영역은 민코프스키 합에 포함됩니다.

 

이제 A의 원점을 B의 테두리를 따라 이동시킨다고 생각해 봅시다. 그때 A가 지나는 모든 영역은 민코프스키 합에 포함됩니다. 그리고 그 내부 역시 민코프스키 합에 포함됩니다.

 

다각형 A, B 둘 다 볼록다각형 1개로 이루어져 있으므로 이렇게 만들어진 영역 역시 볼록다각형입니다.

step 2

더보기

모든 A의 꼭짓점 $(a_x, a_y)$과 모든 B의 꼭짓점 $(b_x,b_y)$에 대해 $(a_x+b_x, a_y+b_y)$를 계산합니다. 각 다각형은 최대 1000개의 꼭짓점을 가지므로 총 1,000,000개의 꼭짓점이 나옵니다.

이 꼭짓점을 모두 포함하는 볼록다각형을 구하면 해결할 수 있습니다.

코드

더보기
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<algorithm>
using namespace std;
struct dataa {
    long long int x, y;
    inline bool operator<(const dataa& temp)const {
        return x<temp.x || x==temp.x && y<temp.y;
    }
}b1[2000],b2[2000],b[1000010],s1[1000100], s2[1000100];
long long int sc1, sc2;
long long int ccw(dataa x,dataa y,dataa z) {
    if (x.x * y.y + y.x * z.y + z.x * x.y - (x.y * y.x + y.y * z.x + z.y * x.x) < 0) return -1;
    if (x.x * y.y + y.x * z.y + z.x * x.y - (x.y * y.x + y.y * z.x + z.y * x.x) > 0) return 1;
    return 0;
}
int main() {
    long long int n, m, i, j;
    scanf("%lld%lld", &n, &m);
    for (i = 1;i <= n;i++) {
        scanf("%lld%lld", &b1[i].x, &b1[i].y);
    }
    long long int cnt = 0;
    for (i = 1;i <= m;i++) {
        scanf("%lld%lld", &b2[i].x, &b2[i].y);
        for (j = 1;j <= n;j++) {
            cnt++;
            b[cnt].x = b1[j].x + b2[i].x;
            b[cnt].y = b1[j].y + b2[i].y;
        }
    }
    sort(b + 1, b + cnt + 1);
    for (i = 1;i <= cnt;i++) {
        while (1) {
            if (sc1 < 2) {
                sc1++;
                s1[sc1] = b[i];
                break;
            }
            if (ccw(s1[sc1 - 1], s1[sc1], b[i]) <= 0) { sc1--; continue; }
            sc1++;
            s1[sc1] = b[i];
            break;
        }
    }
    for (i = 1;i <= cnt;i++) {
        while (1) {
            if (sc2 < 2) {
                sc2++;
                s2[sc2] = b[i];
                break;
            }
            if (ccw(s2[sc2 - 1], s2[sc2], b[i]) >= 0) { sc2--; continue; }
            sc2++;
            s2[sc2] = b[i];
            break;
        }
    }
    printf("%lld\n", sc1 + sc2 - 2);
    for (i = 1;i <= sc1;i++) {
        printf("%lld %lld\n", s1[i].x, s1[i].y);
    }
    for (i = sc2-1;i >= 2;i--) {
        printf("%lld %lld\n", s2[i].x, s2[i].y);
    }
    return 0;
}

'PS - 알고리즘' 카테고리의 다른 글

29845 - Pipes  (0) 2025.02.10
20121 - 카드 셔플  (0) 2025.01.13
10919 - 선물상자  (0) 2024.12.30
18407 - 가로 블록 쌓기  (1) 2024.12.23
2834 - 박스 정렬  (0) 2024.12.16