문제 정보
문제 링크: https://www.acmicpc.net/problem/17441
문제 요약: 단순다각형 \(D\) 내부에서 모기 두 마리의 위치 \(P, Q\)를 균일하게, 그리고 서로 독립적으로 뽑는다. 파리채 제작 비용은 두 점 사이 거리 \(d=|P-Q|\)에 대해 \(d^2\) 이다. 즉, 요구하는 값은
\[ \mathbb{E}\big[|P-Q|^2\big] \]이다.
제한 조건:
- 시간 제한: 1초
- 메모리 제한: 1024MB
- 입력 크기: \(3 \le N \le 100{,}000\)
- 좌표: \(-10{,}000 \le x,y \le 10{,}000\)
- 꼭짓점은 반시계 방향(CCW), 단순다각형 보장
접근 방식
핵심 관찰 1: 두 점 거리 제곱의 기댓값 분해
\(P, Q\)가 서로 독립이고 같은 분포(균일)일 때,
\[ \mathbb{E}\big[|P-Q|^2\big] = \mathbb{E}\big[|P|^2\big] + \mathbb{E}\big[|Q|^2\big] - 2\mathbb{E}[P]\cdot \mathbb{E}[Q] = 2\Big(\mathbb{E}[|P|^2] - |\mathbb{E}[P]|^2\Big) \]가 성립한다.
따라서 필요한 것은 아래 2개다.
- \(\mathbb{E}[P] = (\mathbb{E}[x], \mathbb{E}[y])\): 다각형의 무게중심(centroid)
- \(\mathbb{E}[|P|^2] = \mathbb{E}[x^2+y^2]\): 다각형 내부에서 \(x^2, y^2\)의 면적 적분
핵심 관찰 2: 다각형의 면적 적분을 “변(Edge) 합”으로 계산
단순다각형에 대해 아래 값들은 모두 \(O(N)\)으로 계산 가능하다.
- 면적 \(A = \iint_D 1\, dA\)
- \(\iint_D x\,dA, \iint_D y\,dA\) (무게중심 계산용)
- \(\iint_D x^2\,dA, \iint_D y^2\,dA\)
이는 신발끈 공식/그린 정리(경계 적분으로 환원)로 유도되는 표준 다각형 공식이다.
알고리즘 설계 (Mermaid)
flowchart TD
A["입력: 다각형 꼭짓점 N개 (CCW)"] --> B["모든 변 (i,i+1)에 대해 교차항 cross 누적"]
B --> C["면적 A, 무게중심 (Cx,Cy) 계산"]
C --> D["적분 Ix=∫x^2 dA, Iy=∫y^2 dA 계산"]
D --> E["E2 = (Ix+Iy)/A, mu2 = Cx^2+Cy^2"]
E --> F["정답 = 2*(E2 - mu2) 출력"]
다각형 공식 정리
꼭짓점 \((x_i,y_i)\) (CCW), \(j=i+1\ (\mathrm{mod}\ N)\)라 하자.
\[ \mathrm{cross}_i = x_i y_j - x_j y_i \]면적:
\[ A = \frac{1}{2}\sum_i \mathrm{cross}_i \]무게중심:
\[ C_x = \frac{1}{6A}\sum_i (x_i+x_j)\mathrm{cross}_i,\quad C_y = \frac{1}{6A}\sum_i (y_i+y_j)\mathrm{cross}_i \]2차 모멘트(면적 적분):
\[ \iint_D x^2\,dA = \frac{1}{12}\sum_i (x_i^2+x_ix_j+x_j^2)\mathrm{cross}_i \]\[ \iint_D y^2\,dA = \frac{1}{12}\sum_i (y_i^2+y_iy_j+y_j^2)\mathrm{cross}_i \]
마지막으로
\[ \mathbb{E}[x^2+y^2] = \frac{\iint_D (x^2+y^2)\,dA}{A} \]를 이용해 답을 얻는다.
복잡도 분석
| 항목 | 복잡도 | 비고 |
|---|---|---|
| 시간 복잡도 | \(O(N)\) | 변을 한 번 순회하며 누적합 |
| 공간 복잡도 | \(O(N)\) | 꼭짓점 저장 |
코너 케이스 및 실수 포인트
| 케이스 | 설명 | 처리 방법 |
|---|---|---|
| 비볼록/오목 다각형 | 단순다각형이면 공식은 그대로 성립 | CCW 입력 가정(면적 양수) |
| 정밀도 | 출력 오차 \(1e{-6}\) 허용이지만 누적이 큼 | long double 사용, 충분한 소수 출력 |
| 아주 작은 음수 | 부동소수점 오차로 0 근처에서 -값 가능 | -1e-12 수준은 0으로 보정 |
구현 코드 (C++)
| |
![Featured image of post [Algorithm] C++ 백준 17441번: 파리채 만들기](/post/algorithm/2025-12-19-boj-17441-fly-swatter-making-green-theorem-cpp-solution/wordcloud_hu_2271418efa95bf41.png)
![[Algorithm] C++ 백준 16745번: What Goes Up Must Come Down](/post/algorithm/2025-12-19-boj-16745-what-goes-up-must-come-down-cpp-solution/wordcloud_hu_8b312f25f2104ffa.png)
![[Algorithm] C++ 백준 16895번: 님 게임 3](/post/algorithm/2025-12-19-boj-16895-nim-game-3-cpp-solution/wordcloud_hu_f071b137bed4b6a4.png)
![[Algorithm] C++ 백준 17441번: 파리채 만들기](/post/algorithm/2025-12-19-boj-17441-fly-swatter-making-green-theorem-cpp-solution/wordcloud_hu_f4a8a47eafcd5a3b.png)
![[Algorithm] C++ 백준 1777번: 순열복원](/post/algorithm/2025-12-19-boj-1777-permutation-recovery-cpp-solution/wordcloud_hu_e783e8b2198c2957.png)
![[Algorithm] C++ 백준 17965번: Absolute Game](/post/algorithm/2025-12-19-boj-17965-absolute-game-cpp-solution/wordcloud_hu_f6800a55fcd520be.png)
![[Algorithm] C++ 백준 14853번: 동전 던지기](/post/algorithm/2025-12-19-boj-14853-coin-tossing-cpp-solution/wordcloud_hu_38e38de527bab2db.png)
![[Algorithm] C++ 백준 32231번: 재우의 삼수강](/post/algorithm/2025-12-20-boj-32231-jaewoos-third-retake-hyperbolic-geometry-cpp-solution/wordcloud_hu_6b5d9f28adedfd92.png)
![[Algorithm] C++ 백준 27046번: Beauty Contest](/post/algorithm/2025-12-15-boj-27046-beauty-contest-cpp-solution/wordcloud_hu_36b430743b631c29.png)
![[Algorithm] C++ 백준 20176번: Needle](/post/algorithm/2025-12-19-boj-20176-needle-cpp-solution/wordcloud_hu_d0eac9b197bd7f0d.png)
![[Algorithm] C++ 백준 16481번 원 전문가 진우 - 방접원과 내접원의 관계](/post/algorithm/2025-12-03-boj-16481-excircle-incircle-geometry-cpp-solution/wordcloud_hu_ee675f3393f22f00.png)