방사형 그래프

난이도

Gold 4

인증

문제

게임 캐릭터의 능력치를 한 눈에 보기 좋게 나타내는 방법으로 방사형 그래프가 있다. 캐릭터는 8개의 능력치를 갖고 있고 각 능력치를 $a_1, a_2, \cdots, a_8$이라고 하면, 그래프는 팔각형 형태이고 $k$번째 꼭짓점은 원점을 기준으로 $45\times k$도 방향으로 $a_k$만큼 떨어져 있다.

방사형 그래프를 사용하면 능력치가 얼마나 고르게 분포되어 있는지 쉽게 알 수 있다. 만약 모든 능력치가 동일하다면 정다각형 형태가 되고, 한 능력치가 다른 능력치에 비해 현저히 낮으면 오목 다각형이 된다. 많은 사람들은 방사형 그래프를 볼록 다각형, 즉 모든 내각이 $180°$ 이하인 다각형으로 만들어 자신의 약점을 없애기 위해 노력한다.

시루는 자신의 그래프를 볼록 다각형으로 바꾸고 싶지만, 능력치를 올리는 것은 매우 귀찮기 때문에 한 가지 꼼수를 생각해냈다. 바로 능력치를 나열하는 순서를 바꾸는 것이다. 예를 들어, $\lbrace 6,7,7,8,9,10,11,13 \rbrace$ 순서대로 나열하면 오목 다각형이 되지만, 순서를 바꿔 $\lbrace 7,6,7,8,9,10,11,13 \rbrace$ 순서대로 나열하면 볼록 다각형이 된다.

능력치를 나열하는 순서에 따라 오목 다각형이 될 수도, 볼록 다각형이 될 수도 있기 때문에, 시루는 능력치를 잘 배열해서 볼록 다각형이 되는 경우의 수가 궁금해졌다. 볼록 다각형을 만드는 경우의 수를 구해보자.

입력

첫째 줄에 8개의 능력치를 나타내는 정수 $a_1, a_2, \cdots , a_8$가 공백으로 구분되어 주어진다. ( $1 \leq a_i \leq 10^4$)

출력

8개의 능력치를 잘 배열해서 방사형 그래프를 볼록 다각형으로 만드는 경우의 수를 출력한다.

예제 입력

1 1 1 1 1 1 1 1

예제 출력

40320

해설 및 후기

볼록 및 오목 다각형을 판정하기 위해 역시나 ccw 이론이 사용된다. 각 점을 순회하면서 이전 점과 이후의 점을 얻어내고, 각 점에 대해 좌표를 구한다(각도가 항상 같으므로 편하게 구할 수 있다.) 그 점들을 기준으로 ccw하여 반시계방향이 아닌 시계 방향인지를 체크한다. 만약 그렇다면 이 순열은 볼록 다각형이 아니다.

제출 코드

from math import sin,cos,pi
from itertools import permutations

l = map(int,input().split())
cnt = 0

def ccw(a,b,c):
    res = (b[0]-a[0])*(c[1]-a[1]) - (c[0]-a[0])*(b[1]-a[1])
    if(res < 0):
        return True
    return False

def chk(numLst):
    lstNum = len(numLst)
    for i in range(lstNum):
        a,b,c = numLst[i-1], numLst[i%8], numLst[(i+1)%8]
        a = [0,a]
        b = [b*cos(pi/4),b*sin(pi/4)]
        c = [c,0]
        if(not ccw(a,b,c)):
            return False
    return True

for i in permutations(l,8):
    if(chk(list(i))):
        cnt += 1

print(cnt)