-
[백준] 승부예측 (파이썬)알고리즘 2022. 2. 4. 21:48
문제링크
https://www.acmicpc.net/problem/15997
15997번: 승부 예측
첫 번째 줄에 조별리그를 진행할 국가명 네 개가 공백으로 구분되어 주어진다. 주어지는 모든 국가명은 알파벳 대문자로만 구성된 길이가 1 이상 10 이하인 문자열이다. 두 번째 줄부터 일곱 번
www.acmicpc.net
문제풀이
이 문제는 해결 방법을 떠올리기도 어렵고, 구현하는게 복잡한 문제이다.
총 4개의 팀이 6번의 매치를 하는데 각 매치마다 이기거나, 지거나, 비기는 모든 경우의 확률을
완전탐색한 뒤 1등과 2등을 뽑아 1등과 2등에게 각각의 확률을 더해주는 식으로 문제를 풀면된다.
이 문제를 구현하기 까다로웠는데 그 이유는,
1. 재귀함수와 for 문, 스택을 이용한 완전탐색 구현
2. 데이터 파싱
3. 공동 1,2 등이 나올 각각의 케이스 분류
였다.
모든 매치는 총 3가지 경우의 수가 존재한다.( Win, Lose, Draw )
chance 라는 배열은 각 매치의 결과를 담은 배열이다.
만약 chance 의 길이가 6 일경우, 모든 매치가 종료된 것이므로 이때 1,2 등을 구해 확률을 더해주면 된다.
또한 for 문 밖에 chance.pop() 을 만들어줘서 재귀가 정상적으로 돌아가도록 만들어주었다.
시간복잡도
기본적으로 3^6 의 모든 경우의 수를 탐색하는데,
각 경우마다 k번 의 예외처리를 해주어야 하므로,
TC = 3^6 * k 즉, Big(O) = (3^n) 이다.
소스코드
from collections import defaultdict; teams = list(input().split()); chances = []; ans = defaultdict(list); for team in teams: ans[team] = 0; for i in range(6): temp = list(input().split()); chances.append(temp); def calChance(chance, ans): mm = 1.00000000; d = defaultdict(int); for c in chance: teamA = c[0]; scoreA = int(c[1]); teamB = c[2]; scoreB = int(c[3]); m = float(c[4]); mm *= m; d[teamA] += scoreA; d[teamB] += scoreB; d = dict(sorted(d.items(), key=lambda item : -item[1])); temp = []; for key in d.keys(): temp.append([key, d[key]]); # 2 등이 3등보다 승점이 높은경우 if (temp[1][1] > temp[2][1]): ans[temp[0][0]] += mm; ans[temp[1][0]] += mm; # 2 등이 3등과 점수가 같을 경우 else: # 3,4 등도 2등과 점수가 같은경우 if (temp[2][1] == temp[3][1]): # 1,2 등도 점수가 같은경우 if (temp[0][1] == temp[1][1]): for t in temp: ans[t[0]] += (mm/2); # 1등과 2등이 점수가 같지 않은경우 elif (temp[0][1] != temp[1][1]): ans[temp[0][0]] += mm; ans[temp[1][0]] += mm/3; ans[temp[2][0]] += mm/3; ans[temp[3][0]] += mm/3; # 3등과 4등이 점수가 같지 않은 경우 elif (temp[2][1] != temp[3][1]): # 1 등과 2 등이 점수가 같은 경우 if (temp[0][1] == temp[1][1]): ans[temp[0][0]] += (mm*2)/3; ans[temp[1][0]] += (mm*2)/3; ans[temp[2][0]] += (mm*2)/3; # 1등과 2등이 점수가 같지 않은경우 elif (temp[0][1] != temp[1][1]): ans[temp[0][0]] += mm; ans[temp[1][0]] += mm/2; ans[temp[2][0]] += mm/2; def dfs(level, idx, chance, ans): global chances; nowTeams = chances[level - 1]; if idx == 0: temp = [nowTeams[0], 3,nowTeams[1], 0, nowTeams[idx + 2]]; elif idx == 1: temp = [nowTeams[0], 1,nowTeams[1], 1, nowTeams[idx + 2]]; elif idx == 2: temp = [nowTeams[0], 0,nowTeams[1], 3, nowTeams[idx + 2]]; chance.append(temp); if (level == 6): calChance(chance, ans); chance.pop(); return ; for i in range(3): if float(chances[level][i+2]) != 0: dfs(level + 1, i, chance, ans); chance.pop(); for i in range(3): if float(chances[0][i + 2]) != 0: dfs(1, i, [], ans); for t in teams: print(ans[t]);
'알고리즘' 카테고리의 다른 글
[백준] 최단 경로 (0) 2022.03.01 [프로그래머스] 가장 먼 노드 (0) 2022.02.10 [프로그래머스] 단어변환 (파이썬) (0) 2022.02.03 [프로그래머스] 네트워크 (파이썬) (0) 2022.02.03 [프로그래머스] 타겟넘버 (파이썬) (0) 2022.02.03