๋ฐ˜์‘ํ˜•
Notice
Recent Posts
Recent Comments
Link
ยซ   2025/04   ยป
์ผ ์›” ํ™” ์ˆ˜ ๋ชฉ ๊ธˆ ํ† 
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30
Archives
Today
Total
04-03 16:54
๊ด€๋ฆฌ ๋ฉ”๋‰ด

ImJay

[BOJ/Java] 3628. Knockdown ๋ณธ๋ฌธ

์•Œ๊ณ ๋ฆฌ์ฆ˜/BOJ - Java

[BOJ/Java] 3628. Knockdown

ImJay 2025. 3. 14. 15:12
๋ฐ˜์‘ํ˜•

๐ŸŒ๐Ÿ’ฅ [BOJ/Java] 3628. Knockdown ๐Ÿ’ฃ๐Ÿ”ฅ

๐Ÿ”— ๋ฌธ์ œ ๋งํฌ

๐Ÿ“Œ 3628๋ฒˆ - Knockdown


๐Ÿ“– ๋ฌธ์ œ ํ•ด์„

์ด ๋ฌธ์ œ๋Š” ์ „ ์„ธ๊ณ„๋ฅผ ํŒŒ๊ดดํ•˜๊ธฐ ์œ„ํ•ด ํŠน์ • ์ง€์ ์— ํญํƒ„์„ ๋ฐฐ์น˜ํ•˜๋Š” ์‹œ๋‚˜๋ฆฌ์˜ค๋ฅผ ๋‹ค๋ฃฌ๋‹ค. ๐Ÿ’€๐Ÿ’ฃ
๊ฐ ํญํƒ„์€ ๋™์ผํ•œ ํŒŒ๊ดด ๋ฐ˜๊ฒฝ์„ ๊ฐ€์ง€๋ฉฐ, ์ „ ์„ธ๊ณ„๋ฅผ ํŒŒ๊ดดํ•  ์ˆ˜ ์žˆ๋Š” ์ตœ์†Œํ•œ์˜ ๋ฐ˜๊ฒฝ์„ ์ฐพ์•„์•ผ ํ•œ๋‹ค. ๐ŸŒโžก๏ธ๐Ÿ’ฅ

์ง€๊ตฌ๋Š” ๋ฐ˜์ง€๋ฆ„์ด 1์ธ ๋‹จ์œ„ ๊ตฌ(Sphere) ๋กœ ๋ชจ๋ธ๋ง๋˜๋ฉฐ, ํญํƒ„์˜ ์œ„์น˜๋Š” ์œ„๋„(latitude, φ)์™€ ๊ฒฝ๋„(longitude, λ) ๋กœ ์ฃผ์–ด์ง„๋‹ค.
๊ฑฐ๋ฆฌ๋Š” ๊ตฌ๋ฉด ๊ฑฐ๋ฆฌ(Spherical Distance) ๋กœ ์ธก์ •๋œ๋‹ค. ๐ŸŒ๐Ÿ“


๐Ÿง ํ’€์ด ๊ณผ์ •

1๏ธโƒฃ ๊ตฌ ์ขŒํ‘œ ๋ณ€ํ™˜ (์œ„๋„/๊ฒฝ๋„ → 3D ์ขŒํ‘œ) ๐Ÿ—บ๏ธโžก๏ธ๐Ÿ›ธ

์ง€๊ตฌ๋Š” ๊ตฌํ˜•์ด๋ฏ€๋กœ, ์ฃผ์–ด์ง„ ์œ„๋„์™€ ๊ฒฝ๋„๋ฅผ 3D ์ขŒํ‘œ๊ณ„๋กœ ๋ณ€ํ™˜ํ•ด์•ผ ํ•œ๋‹ค.

์œ„๋„(φ)์™€ ๊ฒฝ๋„(λ)๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋‹ค์Œ ๊ณต์‹์„ ์ด์šฉํ•œ๋‹ค.

x = cos(φ) * cos(λ)  
y = cos(φ) * sin(λ)  
z = sin(φ)

 

์ด์ œ ๊ฐ ํญํƒ„์€ 3D ๊ณต๊ฐ„์˜ ์ (Point) ์œผ๋กœ ๋ณ€ํ™˜๋œ๋‹ค. ๐Ÿ”๏ธ๐ŸŒ


2๏ธโƒฃ ์ตœ์†Œ ๋ฐ˜๊ฒฝ์„ ์ฐพ๊ธฐ ์œ„ํ•œ ์ ‘๊ทผ ๋ฐฉ์‹ ๐Ÿ”๐ŸŽฏ

๋ชฉํ‘œ๋Š” ์–ด๋Š ์ง€์ ์—์„œ๋“  ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ํญํƒ„๊นŒ์ง€์˜ ๊ฑฐ๋ฆฌ๊ฐ€ ์ตœ์†Œ ๋ฐ˜๊ฒฝ r ์ดํ•˜๊ฐ€ ๋˜๋„๋ก ํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

์ฆ‰, ์ง€๊ตฌ์ƒ์˜ ๋ชจ๋“  ์ ์ด ์–ด๋–ค ํญํƒ„๊ณผ๋„ ์ตœ๋Œ€ r ๊ฑฐ๋ฆฌ ์ด๋‚ด์— ์žˆ๋„๋ก ๋ณด์žฅํ•ด์•ผ ํ•œ๋‹ค.
์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด, ์ด๋ถ„ ํƒ์ƒ‰(์ด์ง„ ํƒ์ƒ‰) + ๊ธฐํ•˜ํ•™์  ๊ณ„์‚ฐ์„ ํ™œ์šฉํ•œ๋‹ค. โš™๏ธ๐Ÿงฎ

๐Ÿ”น ๊ณ ๋ คํ•ด์•ผ ํ•  ํ›„๋ณด ์ ๋“ค

  1. ๊ฐ ํญํƒ„์˜ ๋ฐ˜๋Œ€ํŽธ ์  (Antipodal Point)
    • ํญํƒ„์ด ์œ„์น˜ํ•œ ์ ์˜ ์ •๋ฐ˜๋Œ€ ์ง€์ ์ด ์œ ๋ ฅํ•œ ํ›„๋ณด๊ฐ€ ๋œ๋‹ค.
    • ์ด๋Š” (−x,−y,−z)(-x, -y, -z) ๋กœ ์‰ฝ๊ฒŒ ๊ตฌํ•  ์ˆ˜ ์žˆ๋‹ค.
  2. ๋‘ ํญํƒ„ ์‚ฌ์ด์˜ ์ค‘๊ฐ„์  (Pairwise Midpoint)
    • ๋‘ ๊ฐœ์˜ ํญํƒ„์ด ์žˆ๋‹ค๋ฉด, ์ด๋“ค์˜ ์ค‘๊ฐ„ ๋ฒกํ„ฐ ๋ฐฉํ–ฅ์ด ์ ์ ˆํ•œ ํ›„๋ณด๊ฐ€ ๋  ์ˆ˜ ์žˆ๋‹ค.
  3. ์„ธ ํญํƒ„์œผ๋กœ ์ด๋ฃจ์–ด์ง„ ์ •์  (Triple-wise Normal Vector)
    • ์„ธ ๊ฐœ์˜ ํญํƒ„์ด ํ˜•์„ฑํ•˜๋Š” ํ‰๋ฉด์˜ ๋ฒ•์„  ๋ฒกํ„ฐ๊ฐ€ ์œ ๋ ฅํ•œ ํ›„๋ณด๊ฐ€ ๋œ๋‹ค.

๐Ÿ”น ์ตœ์ ํ™” ๋ชฉํ‘œ: min max(dot product)

 

๊ฐ ํ›„๋ณด ์ง€์ ์—์„œ ๋ชจ๋“  ํญํƒ„๊ณผ์˜ ์ตœ๋Œ€ ๋‚ด์ (dot product) ๊ฐ’์„ ์ตœ์†Œํ™”ํ•˜๋Š” p๋ฅผ ์ฐพ์•„์•ผ ํ•œ๋‹ค.
์ด ๊ฐ’์ด ์ž‘์„์ˆ˜๋ก ์ตœ์ ์˜ ๋ฐ˜๊ฒฝ์ด ์ค„์–ด๋“ ๋‹ค.

์ตœ์†Œ ๋ฐ˜๊ฒฝ์€ acos(์ตœ์ ์˜ ๋‚ด์  ๊ฐ’) ์œผ๋กœ ๊ณ„์‚ฐ๋œ๋‹ค.

r = arccos(min max(p · bomb_i))

๐Ÿ’ป ์ฝ”๋“œ ๊ตฌํ˜„ (Java)

import java.io.*;
import java.util.*;

public class Main {
    static final double EPS = 1e-9;  // ์˜ค์ฐจ ํ—ˆ์šฉ ๋ฒ”์œ„

    // 3์ฐจ์› ์ขŒํ‘œ๋ฅผ ์ €์žฅํ•˜๋Š” ํด๋ž˜์Šค
    static class Point {
        double x, y, z;
        Point(double x, double y, double z) {
            this.x = x; this.y = y; this.z = z;
        }
        Point add(Point p) { return new Point(x + p.x, y + p.y, z + p.z); }
        Point subtract(Point p) { return new Point(x - p.x, y - p.y, z - p.z); }
        Point multiply(double s) { return new Point(x * s, y * s, z * s); }
        double dot(Point p) { return x * p.x + y * p.y + z * p.z; }  // ๋‚ด์ 
        Point cross(Point p) {  // ์™ธ์ 
            return new Point(y * p.z - z * p.y,
                             z * p.x - x * p.z,
                             x * p.y - y * p.x);
        }
        double norm() { return Math.sqrt(x * x + y * y + z * z); }  // ๋ฒกํ„ฐ ํฌ๊ธฐ
        Point normalize() {  // ๋‹จ์œ„ ๋ฒกํ„ฐ ๋ณ€ํ™˜
            double n = norm();
            if(n < EPS) return new Point(0, 0, 0);
            return new Point(x / n, y / n, z / n);
        }
    }

    static double candidateValue(Point p, Point[] bombs) {
        double val = -1e9;
        for (Point b : bombs) {
            val = Math.max(val, p.dot(b));
        }
        return val;
    }

    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        PrintWriter out = new PrintWriter(System.out);

        int n = Integer.parseInt(br.readLine().trim());
        Point[] bombs = new Point[n];

        for (int i = 0; i < n; i++) {
            String[] parts = br.readLine().trim().split("\\s+");
            double lat = Math.toRadians(Double.parseDouble(parts[0]));
            double lon = Math.toRadians(Double.parseDouble(parts[1]));
            double cosLat = Math.cos(lat);
            bombs[i] = new Point(cosLat * Math.cos(lon), cosLat * Math.sin(lon), Math.sin(lat));
        }

        double best = 1e9;

        for (int i = 0; i < n; i++) {
            Point cand = new Point(-bombs[i].x, -bombs[i].y, -bombs[i].z);
            best = Math.min(best, candidateValue(cand, bombs));
        }

        for (int i = 0; i < n; i++) {
            for (int j = i+1; j < n; j++) {
                Point sum = bombs[i].add(bombs[j]);
                if (sum.norm() > EPS) {
                    best = Math.min(best, candidateValue(sum.multiply(-1).normalize(), bombs));
                }
            }
        }

        for (int i = 0; i < n; i++) {
            for (int j = i+1; j < n; j++) {
                for (int k = j+1; k < n; k++) {
                    Point cross = bombs[i].subtract(bombs[j]).cross(bombs[i].subtract(bombs[k]));
                    if (cross.norm() > EPS) {
                        best = Math.min(best, candidateValue(cross.normalize(), bombs));
                        best = Math.min(best, candidateValue(cross.multiply(-1).normalize(), bombs));
                    }
                }
            }
        }

        best = Math.max(-1, Math.min(1, best));
        double ans = Math.acos(best);
        out.printf("%.6f\n", ans);
        out.flush();
    }
}

โณ ์‹œ๊ฐ„ ๋ณต์žก๋„ ๋ถ„์„

  • ๊ฐ ํญํƒ„๋งˆ๋‹ค ํ›„๋ณด ํƒ์ƒ‰O(n)
  • ๋‘ ๊ฐœ์˜ ํญํƒ„์„ ์ด์šฉํ•œ ํ›„๋ณด ํƒ์ƒ‰O(n^2)
  • ์„ธ ๊ฐœ์˜ ํญํƒ„์„ ์ด์šฉํ•œ ํ›„๋ณด ํƒ์ƒ‰O(n^3)
  • ์ตœ๋Œ€ ํญํƒ„ ๊ฐœ์ˆ˜ n=20n = 20 ์ด๋ฏ€๋กœ ์ตœ์•…์˜ ๊ฒฝ์šฐ O(8000), ์ถฉ๋ถ„ํžˆ ์‹คํ–‰ ๊ฐ€๋Šฅ โœ…

๐Ÿ’ก ๋Š๋‚€ ์ 

โœ… ๊ตฌ๋ฉด ๊ธฐํ•˜ํ•™๊ณผ ์ด๋ถ„ ํƒ์ƒ‰์„ ์กฐํ•ฉํ•œ ํฅ๋ฏธ๋กœ์šด ๋ฌธ์ œ์˜€๋‹ค! ๐ŸŒโœจ
โœ… ํญํƒ„์ด ์ตœ์†Œํ•œ์œผ๋กœ ์ปค๋ฒ„ํ•ด์•ผ ํ•  ๋ฒ”์œ„๋ฅผ ์ฐพ๋Š” ๊ณผ์ •์ด ๊ธฐํ•˜ํ•™์ ์œผ๋กœ ์žฌ๋ฏธ์žˆ์—ˆ๋‹ค. ๐ŸŽฏ๐Ÿ”ฅ
โœ… ๋ฒกํ„ฐ ์—ฐ์‚ฐ(๋‚ด์ , ์™ธ์ , ๋‹จ์œ„ ๋ฒกํ„ฐ ๋ณ€ํ™˜) ์˜ ์ค‘์š”์„ฑ์„ ๋‹ค์‹œ ํ•œ๋ฒˆ ์ฒด๊ฐํ–ˆ๋‹ค! ๐Ÿš€

๋ฐ˜์‘ํ˜•

'์•Œ๊ณ ๋ฆฌ์ฆ˜ > BOJ - Java' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

[BOJ/Java] 12422. ์ฐฝ๋ฌธ ๊นจ๊ธฐ (Large)  (1) 2025.03.14
[BOJ/Java] 6902. Orko  (1) 2025.03.13
[BOJ/Java] 5266. Strange Dream  (0) 2025.03.13
[BOJ/Java] 11404. ํ”Œ๋กœ์ด๋“œ  (1) 2025.03.10
[BOJ/Java] 2931. ๊ฐ€์Šค๊ด€  (0) 2025.03.10
Comments