snowflake 님의 풀이를 보고 영감을 받아 작성한 글입니다.
문제에서 제시한 내용은 어떤 다각형이 주어질 때, 다각형 내의 임의의 두 점 사이 거리 제곱의 기댓값을 구하라는 것입니다.
다각형 내의 점은 연속적으로 분포하므로 적분을 사용해주어야 합니다.
다각형의 넓이를 S라고 하고, 임의의 두 점의 좌표를 각각 (x1,y1), (x2,y2) 라 정의해줍니다.
이 때, 두 점 사이 거리의 제곱은 (x1−x2)2+(y1−y2)2이고, 두 점 주변의 미소면적
dA1=ax1ay1
dA2=ax2ay2
를 잡았을 때,
전체 다각형 영역 중에서 각 미소면적 내의 점을 독립적으로 하나씩 택할 확률은
S2dA1dA2
라는 사실을 쉽게 알아낼 수 있습니다.
이 후, 기댓값 E는
E=S21∬S∬S(x1−x2)2+(y1−y2)2dA1dA2=S21∬S∬S(x12+x22−2x1x2+y12+y22−2y1y2)dA1dA2
라는 적분식으로 계산될 수 있습니다. 여기서 조금 더 하면
∬S∬Sx12dA1dA2=(∬Sx2dA)(∬SdA)=S(∬Sx2dA)=∬S∬Sx22dA1dA2,
- ∬S∬Sx1x2dA1dA2=(∬Sx1dA1)(∬Sx2dA2)=(∬SxdA)2
- y12,y22 항을 적분하면 각각 S(∬Sy2dA)라는 식이 되고, y1y2 항을 적분하면 (∬SydA)2라는 식이 됩니다.
이 때,
A=∬Sx2+y2dA
B=∬SxdA
C=∬SydA
라고 정의하면 E에 대해
E=S21(2AS−2B2−2C2)
라고 정리할 수 있습니다.
이 때, 이중적분을 그대로 계산하는 것은 힘듭니다. 그러므로 우리는 이 이중적분을 선적분으로 바꾸어줄 필요가 있습니다. 이를 그린 정리를 활용하여 진행할 것입니다.
A는 그린 정리에 의하여
A=∮∂S−31y3dx+31x3dy=31i=1∑N∫(xi,yi)(xi+1,yi+1)x3dy−y3dx
가 됩니다. 이 때 (xi,yi)는 다각형의 i번째 꼭짓점이고, 첫번째 점은 N+1번째 점입니다. i번째 변은 y=xi+1−xiyi+1−yi(x−xi)+yi 로 표현 가능하므로
dx=yi+1−yixi+1−xidy
dy=xi+1−xiyi+1−yidx
가 됩니다. 이를 첫 번째와 두 번째 항에 대입하고 정적분을 계산하면
A=121i=1∑N{(yi+1−yi)(xi3+xi2xi+1+xixi+12+xi+13)−(xi+1−xi)(yi3+yi2yi+1+yiyi+12+yi+13)}
가 됩니다. 여기서 식을 더 정리해봅시다.
xi+12xiyi+1+xi+1xi2yi+1+xi3yi+1−xi+13yi−xi+12xiyi−xi+1xi2yi=(xiyi+1−xi+1yi)(xi2+xixi+1+xi+12)
∴ A=121i=1∑N(xiyi+1−xi+1yi)(xi2+xixi+1+xi+12+yi2+yiyi+1+yi+12)
위와 같은 과정을 B,C 에서도 진행할 수 있고, 이를 위의 식에 삽입하면 문제의 답인 기댓값을 얻을 수 있습니다.
a = n_x = n_y = i_x = i_y = 0
n = int(input())
x = [0 for _ in range(n)]
y = [0 for _ in range(n)]
for i in range(n):
x[i], y[i] = map(int, input().split())
for i in range(1, n - 1):
a += ((x[i] - x[0]) * (y[i + 1] - y[0]) - (x[i + 1] - x[0]) * (y[i] - y[0])) / 2
for i in range(n):
n_x += ((x[(i + 1) % n] ** 3 + x[(i + 1) % n] ** 2 * x[i] + x[(i + 1) % n] * x[i] ** 2 + x[i] ** 3) * (y[(i + 1) % n] - y[i])) / 12
n_y += ((y[(i + 1) % n] ** 3 + y[(i + 1) % n] ** 2 * y[i] + y[(i + 1) % n] * y[i] ** 2 + y[i] ** 3) * (x[(i + 1) % n] - x[i])) / -12
i_x += ((x[(i + 1) % n] ** 2 + x[(i + 1) % n] * x[i] + x[i] ** 2) * (y[(i + 1) % n] - y[i])) / 6
i_y += ((y[(i + 1) % n] ** 2 + y[(i + 1) % n] * y[i] + y[i] ** 2) * (x[(i + 1) % n] - x[i])) / -6
print((a * n_x + a * n_y - i_x ** 2 - i_y ** 2) * 2 / a ** 2)