3 minute read

Voronoi Diagram Returns

๋ฌธ์ œ ์ถœ์ฒ˜

2018 KAIST 8th ACM-ICPC Mock Competition L๋ฒˆ

๋ฌธ์ œ ๋ฒˆ์—ญ

๋‹ค์Œ์€ ์ œ๊ฐ€ ์ž„์˜๋กœ ๋ฒˆ์—ญํ•œ ๋‚ด์šฉ์ž…๋‹ˆ๋‹ค.

๋ฌธ์ œ

voronoi diagram

๊ทธ๋ฆผ: ํฌ๊ธฐ 4์˜ ๋ณด๋กœ๋…ธ์ด ๋‹ค์ด์–ด๊ทธ๋žจ.

2์ฐจ์› ์ง๊ต ์ขŒํ‘œ๊ณ„์—์„œ, ๋น„์–ด ์žˆ์ง€ ์•Š์€ ์ ์˜ ์ง‘ํ•ฉ $S$์— ๋Œ€ํ•œ ๋ณด๋กœ๋…ธ์ด ๋‹ค์ด์–ด๊ทธ๋žจ(Voronoi Diagram)์€ ํ‰๋ฉด์„ โ€œ์ด ์œ„์น˜์—์„œ ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ์ ์ด ๋ฌด์—‡์ธ๊ฐ€?โ€๋ผ๋Š” ๊ธฐ์ค€์œผ๋กœ ๋‚˜๋ˆˆ ๋„ํ˜•์ด๋‹ค.

์ข€ ๋” ์ •ํ™•ํžˆ ๋งํ•˜๋ฉด, ์ ์˜ ์ง‘ํ•ฉ ${P_1, P_2, \cdots, P_n}$์— ๋Œ€ํ•œ ๋ณด๋กœ๋…ธ์ด ๋‹ค์ด์–ด๊ทธ๋žจ์€ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์˜์—ญ์œผ๋กœ ๋‚˜๋‰˜๋ฉฐ, ์ž„์˜์˜ ์  $K$๊ฐ€ $i$๋ฒˆ ์˜์—ญ์— ์†ํ•œ๋‹ค๋Š” ๊ฒƒ์€ ๋‹ค์Œ ์กฐ๊ฑด์„ ๋งŒ์กฑํ•  ๋•Œ์ด๋‹ค.

๋ชจ๋“  $1 \le j \le n$์— ๋Œ€ํ•˜์—ฌ, ์  $K$์™€ $P_i$ ์‚ฌ์ด์˜ ์œ ํด๋ฆฌ๋“œ ๊ฑฐ๋ฆฌ๊ฐ€ ์  $K$์™€ $P_j$ ์‚ฌ์ด์˜ ๊ฑฐ๋ฆฌ๋ณด๋‹ค ์ž‘๊ฑฐ๋‚˜ ๊ฐ™์•„์•ผ ํ•œ๋‹ค. ์ฆ‰, $d(P_i, K) \le d(P_j, K)$์ด๋‹ค.

์—ฌ๊ธฐ์„œ $d(X, Y)$๋Š” ์  $X$์™€ ์  $Y$ ์‚ฌ์ด์˜ ์œ ํด๋ฆฌ๋“œ ๊ฑฐ๋ฆฌ์ด๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด, ์œ„ ๊ทธ๋ฆผ์—์„œ๋Š” ํ‰๋ฉด์ƒ์˜ ๋ชจ๋“  ์œ„์น˜๊ฐ€ ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ์ ์— ๋”ฐ๋ผ ์ƒ‰์น ๋˜์–ด ์žˆ๋‹ค.
ํ•˜๋‚˜์˜ ์˜์—ญ์—๋งŒ ์†ํ•˜๋Š” ์ ์€ ๋ฐ์€ ์ƒ‰์œผ๋กœ, ๋‘ ๊ฐœ ์ด์ƒ์˜ ์˜์—ญ์— ๋™์‹œ์— ์†ํ•˜๋Š” ์ ์€ ๊ฒ€์€ ์„ ์ด๋‚˜ ์ ์œผ๋กœ ๋‚˜ํƒ€๋‚œ๋‹ค.

$\mathcal{O}(n \log n)$ ์‹œ๊ฐ„์— ๋ณด๋กœ๋…ธ์ด ๋‹ค์ด์–ด๊ทธ๋žจ์„ ๊ตฌ์„ฑํ•˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด ์กด์žฌํ•˜์ง€๋งŒ, ์ด ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ๊ตฌํ˜„์ด ๋ณต์žกํ•˜๊ณ  ์–ด๋ ต๊ธฐ๋กœ ์œ ๋ช…ํ•˜๋‹ค.
ํ•˜์ง€๋งŒ ์šฐ๋ฆฌ๋Š” ๋„ˆ๊ทธ๋Ÿฌ์šด ์ถœ์ œ์ž์ด๋ฏ€๋กœ, $n \le 2000$๋งŒ ์ฃผ์–ด์ง€๋ฉฐ, ์ด๋Š” ๋” ๋А๋ฆฐ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์‚ฌ์šฉํ•ด๋„ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค.

์ด ๋ฌธ์ œ์—์„œ๋Š” ๋ณด๋กœ๋…ธ์ด ๋‹ค์ด์–ด๊ทธ๋žจ ์œ„์—์„œ ์ฃผ์–ด์ง„ ์ฟผ๋ฆฌ์˜ ์ ์ด ์–ด๋А ์˜์—ญ์— ์†ํ•˜๋Š”์ง€๋ฅผ ํŒ๋‹จํ•˜๋Š” ์  ์ฟผ๋ฆฌ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•ด์•ผ ํ•œ๋‹ค.
์ ์˜ ์ง‘ํ•ฉ ${P_1, P_2, \cdots, P_n}$์œผ๋กœ ๊ตฌ์„ฑ๋œ ๋ณด๋กœ๋…ธ์ด ๋‹ค์ด์–ด๊ทธ๋žจ๊ณผ $q$๊ฐœ์˜ ์  ์ฟผ๋ฆฌ๊ฐ€ ์ฃผ์–ด์งˆ ๋•Œ, ๊ฐ ์  ์ฟผ๋ฆฌ ์— ๋Œ€ํ•ด ๋‹ค์Œ ์ค‘ ์–ด๋””์— ์†ํ•˜๋Š”์ง€๋ฅผ ํŒ๋ณ„ํ•ด์•ผ ํ•œ๋‹ค:

  • ์–ด๋–ค ์˜์—ญ์—๋„ ์†ํ•˜์ง€ ์•Š์œผ๋ฉด NONE์„ ์ถœ๋ ฅํ•œ๋‹ค.
  • ์ •ํ™•ํžˆ ํ•˜๋‚˜์˜ ์˜์—ญ์—๋งŒ ์†ํ•˜๋ฉด REGION X๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค. ์—ฌ๊ธฐ์„œ $X$๋Š” ํ•ด๋‹น ์˜์—ญ์˜ ์ธ๋ฑ์Šค์ด๋‹ค.
  • ์ •ํ™•ํžˆ ๋‘ ๊ฐœ์˜ ์˜์—ญ์— ์†ํ•˜๋ฉด LINE X Y๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค. ์—ฌ๊ธฐ์„œ $X$์™€ $Y$๋Š” ํ•ด๋‹น ๋‘ ์˜์—ญ์˜ ์ธ๋ฑ์Šค์ด๋ฉฐ, $X < Y$๋ฅผ ๋งŒ์กฑํ•ด์•ผ ํ•œ๋‹ค.
  • ์„ธ ๊ฐœ ์ด์ƒ์˜ ์˜์—ญ์— ์†ํ•˜๋ฉด POINT๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค.

์ž…๋ ฅ

์ฒซ์งธ ์ค„์— ๋ณด๋กœ๋…ธ์ด ๋‹ค์ด์–ด๊ทธ๋žจ์„ ๊ตฌ์„ฑํ•˜๋Š” ์ ์˜ ๊ฐœ์ˆ˜ $n$๊ณผ ์ฟผ๋ฆฌ์˜ ๊ฐœ์ˆ˜ $q$๊ฐ€ ์ฃผ์–ด์ง„๋‹ค.
($3 \le n \le 2, 000,\ 1 \le q \le 250, 000$)

๋‹ค์Œ $n$๊ฐœ์˜ ์ค„์—๋Š” ๊ฐ ์  $P_i$์˜ $x$, $y$ ์ขŒํ‘œ๊ฐ€ ์ฃผ์–ด์ง„๋‹ค. ์ด ์ ๋“ค์€ ๋ณด๋กœ๋…ธ์ด ๋‹ค์ด์–ด๊ทธ๋žจ์„ ๊ตฌ์„ฑํ•˜๋Š” ์ ๋“ค์ด๋‹ค.
๋ชจ๋“  ์ ์€ ์„œ๋กœ ๋‹ค๋ฅด๋‹ค. ($|x|,\ |y| \le 10,000$)

$j$๋ฒˆ์งธ ์ค„๋ถ€ํ„ฐ, $q$๊ฐœ์˜ ์ค„์—๋Š” ๊ฐ ์  ์ฟผ๋ฆฌ $Q_j$์˜ $x$, $y$ ์ขŒํ‘œ๊ฐ€ ์ฃผ์–ด์ง„๋‹ค.
๊ฐ ์  ์ฟผ๋ฆฌ์— ๋Œ€ํ•ด, ํ•ด๋‹น ์ ์ด ์–ด๋А ๋ณด๋กœ๋…ธ์ด ์˜์—ญ์— ์†ํ•˜๋Š”์ง€ ํŒ๋‹จํ•ด์•ผ ํ•œ๋‹ค. ($|x|,\ |y| \le 10,000$)

์ถœ๋ ฅ

์ถœ๋ ฅ์€ ์ด $q$์ค„๋กœ ๊ตฌ์„ฑ๋œ๋‹ค.
$j$๋ฒˆ์งธ ์ค„์—๋Š” ๋‹ค์Œ ์ค‘ ํ•˜๋‚˜๋ฅผ ์ถœ๋ ฅํ•ด์•ผ ํ•œ๋‹ค.

  • ๋งŒ์•ฝ $Q_j$๊ฐ€ ์–ด๋–ค ์˜์—ญ์—๋„ ํฌํ•จ๋˜์ง€ ์•Š๋Š”๋‹ค๋ฉด, NONE์„ ์ถœ๋ ฅํ•œ๋‹ค.
  • ๋งŒ์•ฝ $Q_j$๊ฐ€ ์ •ํ™•ํžˆ ํ•˜๋‚˜์˜ ์˜์—ญ์— ํฌํ•จ๋˜์–ด ์žˆ๋‹ค๋ฉด, REGION X๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค. ์—ฌ๊ธฐ์„œ $X$๋Š” ํ•ด๋‹น ์˜์—ญ์˜ ์ธ๋ฑ์Šค์ด๋‹ค.
  • ๋งŒ์•ฝ $Q_j$๊ฐ€ ์ •ํ™•ํžˆ ๋‘ ์˜์—ญ์— ํฌํ•จ๋˜์–ด ์žˆ๋‹ค๋ฉด, LINE X Y๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค. ์—ฌ๊ธฐ์„œ $X$์™€ $Y(X < Y)$๋Š” ํ•ด๋‹น ๋‘ ์˜์—ญ์˜ ์ธ๋ฑ์Šค์ด๋‹ค.
  • ๋งŒ์•ฝ $Q_j$๊ฐ€ 3๊ฐœ ์ด์ƒ์˜ ์ง€์—ญ์— ํฌํ•จ๋˜์–ด ์žˆ๋Š” ๊ฒฝ์šฐ POINT๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค.

ํ’€์ด

๋ณด๋กœ๋…ธ์ด ๋‹ค์ด์–ด๊ทธ๋žจ(voronoi diagram)์„ ์ดํ•ดํ•˜๊ณ  ์žˆ์œผ๋ฉด ๋ฌธ์ œ๋ฅผ ๊ธˆ๋ฐฉ ์ดํ•ดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. voronoi diagram์ด๋ž€ ๊ฐ„๋‹จํ•˜๊ฒŒ ๋งํ•˜์ž๋ฉด ํ‰๋ฉด์„ ํŠน์ • ์ ๊นŒ์ง€์˜ ๊ฑฐ๋ฆฌ๊ฐ€ ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ์ ์˜ ์ง‘ํ•ฉ์œผ๋กœ ๋ถ„ํ• ํ•œ ๊ทธ๋ฆผ์ž…๋‹ˆ๋‹ค. ๋‹คํ–‰ํžˆ๋„ ๋ฌธ์ œ์—์„œ ์„ค๋ช…์„ ์‰ฝ๊ฒŒ ํ•ด์ค˜์„œ ์‚ฌ์ „์ง€์‹ ์—†์ด๋„ ํ’€ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์›๋ž˜๋ผ๋ฉด ๋ณด๋กœ๋…ธ์ด ๋‹ค์ด์–ด๊ทธ๋žจ ๋ฌธ์ œ๋Œ€๋กœ ํ’€์–ด์•ผํ•˜์ง€๋งŒ, ์ด ๋ฌธ์ œ๋Š” ๋„ˆ๊ทธ๋Ÿฌ์šด ์ถœ์ œ์ž ๋ถ„๋“ค์ด ์‹œ๊ฐ„์ œํ•œ์„ ๋ฌด๋ ค 10์ดˆ๋กœ ๋งŒ๋“ค์–ด์ฃผ์…จ๊ธฐ ๋•Œ๋ฌธ์— ์ฟผ๋ฆฌ๋‹น $O(n)$์— ํ’€ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ˜„์žฌ ์ ์—์„œ ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ์ ๋“ค์˜ ๊ฐœ์ˆ˜๋ฅผ countํ•˜์—ฌ ๊ทธ ๊ฐœ์ˆ˜์— ๋”ฐ๋ผ ๋ฌธ์ œ์—์„œ ์š”๊ตฌํ•˜๋Š” ์ถœ๋ ฅ์„ ์‹คํ–‰ํ•˜๋ฉด ๋˜๋Š” ๊ฐ„๋‹จํ•œ ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค.

์ฟผ๋ฆฌ๋งˆ๋‹ค ๋ณด๋กœ๋…ธ์ด ๋‹ค์ด์–ด๊ทธ๋žจ์„ ๊ตฌ์„ฑํ•˜๋Š” $n$๊ฐœ์˜ ์ ์„ ๋ฐ˜๋ณต๋ฌธ์„ ๋Œ๋ฉฐ ํ•ด๋‹น ์ฟผ๋ฆฌ ์ ์—์„œ์˜ ์œ ํด๋ฆฌ๋“œ ๊ฑฐ๋ฆฌ๊ฐ€ ๊ฐ€์žฅ ์ž‘์€ ๊ฐ’์„ ์ €์žฅํ•˜๊ณ , ์ธ๋ฑ์Šค๋ฅผ ๋ฐฐ์—ด์— ์ €์žฅํ•ฉ๋‹ˆ๋‹ค. ๋งŒ์•ฝ ์œ ํด๋ฆฌ๋“œ ๊ฑฐ๋ฆฌ๊ฐ€ ์ €์žฅ๋œ ์ตœ์†Ÿ๊ฐ’๊ณผ ๊ฐ™๋‹ค๋ฉด ์ธ๋ฑ์Šค๋ฅผ ๋ฐฐ์—ด์— ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ์ดํ›„ ์ธ๋ฑ์Šค ๋ฐฐ์—ด์˜ ํฌ๊ธฐ์— ๋”ฐ๋ผ ์ถœ๋ ฅ์„ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

์ „์ฒด ์ฝ”๋“œ

#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
using namespace std;

int main() {
    cin.tie(nullptr)->sync_with_stdio(false);

    int n, q;
    cin >> n >> q;
    vector<pair<int, int>> coordinate(n);
    for(int i = 0; i < n; i++)
        cin >> coordinate[i].first >> coordinate[i].second;

    while(q--) {
        int qx, qy;
        cin >> qx >> qy;

        int minDist = 1e9;
        vector<int> idx;

        for(int j = 0; j < n; j++) {
            int dx = qx - coordinate[j].first;
            int dy = qy - coordinate[j].second;
            int dist = dx*dx + dy*dy;

            if(dist < minDist) {
                minDist = dist;
                idx = {j};
            }
            else if(dist == minDist) idx.emplace_back(j);
        }

        if(idx.empty()) cout << "NONE" << '\n';
        else if(idx.size() == 1) cout << "REGION" << ' ' << idx[0]+1 << '\n';
        else if(idx.size() == 2) cout << "LINE" << ' ' << idx[0]+1 << ' ' << idx[1]+1 << '\n';
        else cout << "POINT" << '\n';
    }

    return 0;
}

Comments