알고리즘/BOJ

[BOJ/python] 6987번 월드컵

frog-in-well 2022. 7. 1. 21:22

백준 6987번 월드컵 파이썬

문제 출처 - https://www.acmicpc.net/problem/6987

 

6987번: 월드컵

월드컵 조별 최종 예선에서는 6개국으로 구성된 각 조별로 동일한 조에 소속된 국가들과 한 번씩, 각 국가별로 총 5번의 경기를 치른다. 조별리그가 끝난 후, 기자가 보내온 각 나라의 승, 무승부

www.acmicpc.net

제발 시간 복잡도 계산했는데 안되면 다른 방법을 생각하자. 처음에는 결과 배열 마다 따로 함수를 수행하지 않고 마지막 15 라운드에서 4개의 배열과 각각 비교하는 방식으로 풀었다. 결과 배열에서 -1을 하며 재귀를 수행하는 것이 아니라 0에서 부터 모든 경우를 구하기 때문에 가지치기를 할 수 있는 방법이 없다. 즉 시간 복잡도가 O(3**15)가 된다. (아슬아슬하게 틀리는 것 같다.) 결과 배열에서 -1을 하며 재귀를 수행하면 가지치기가 가능해서 쉽게 풀 수 있다.

1. 풀이

  • 각각의 결과 배열마다 DFS 함수를 수행하여 가능한 결과인지 판단한다.
  • 6팀이 경기할 수 있는 경우의 수는 총 15가지이다. home,away에 순서쌍을 인자로 넣어 재귀함수를 수행한다.
  • 재귀 함수마다 home이 이긴 경우, 비기는 경우, 지는 경우에 결과 배열에서 -1을 한 뒤 다음 재귀로 넘긴다. 이 때 결과 배열의 값이 0보다 작다면 수행하지 않는다.
  • 마지막 E와 F 경기까지 재귀 함수를 수행하고 얻은 결과 배열이 가능한 결과라면 [ [0,0,0] for _ in range(6) ] 일 것이다.

2. 코드

from itertools import combinations

def DFS(home,away):
    global L, tmp
    
    if away==6:
        home+=1
        away=home+1
    
    if home==5:
        if L==[ [0,0,0] for _ in range(6) ]:
            tmp=1
        return

    #home이 이긴경우
    if L[home][0]>0 and L[away][2]>0:
        L[home][0], L[away][2] = L[home][0]-1, L[away][2]-1
        DFS(home,away+1)
        L[home][0], L[away][2] = L[home][0]+1, L[away][2]+1
    
    #home이 지는경우
    if L[home][2]>0 and L[away][0]>0:
        L[home][2], L[away][0] = L[home][2]-1, L[away][0]-1
        DFS(home,away+1)
        L[home][2], L[away][0] = L[home][2]+1, L[away][0]+1
    
    #비기는 경우
    if L[home][1] and L[away][1]>0 :
        L[home][1], L[away][1] = L[home][1]-1, L[away][1]-1
        DFS(home,away+1)
        L[home][1], L[away][1] = L[home][1]+1, L[away][1]+1

sol = []
for round in range(4):
    question = list(map(int, input().split())) 
    L = []
    for i in range(6):
        L.append([question[i*3],question[(i*3)+1],question[(i*3)+2] ])
    
    tmp = 0
    DFS(0,1)
    sol.append(tmp)
    
print(*sol)