Processing math: 44%

방사형 그래프

난이도

Gold 4

인증

문제

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

방사형 그래프를 사용하면 능력치가 얼마나 고르게 분포되어 있는지 쉽게 알 수 있다. 만약 모든 능력치가 동일하다면 정다각형 형태가 되고, 한 능력치가 다른 능력치에 비해 현저히 낮으면 오목 다각형이 된다. 많은 사람들은 방사형 그래프를 볼록 다각형, 즉 모든 내각이 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)