새소식

PS/백준

[백준/30795] 가희와 총선거 5 (Python)

  • -

Problem : https://www.acmicpc.net/problem/30795

 

30795번: 가희와 총선거 5

선거할 때마다 반드시 나타나는 신데렐라를 아시나요? 신데렐라는 예상과 다르게 경악할 정도로 뛰어난 결과를 보여준 캐릭터를 의미합니다. 신데렐라 수치는 티어와 예상 결과, 최종 결과와

www.acmicpc.net

 

Difficulty : Gold 3

 

Status : Solved

 

Time : 00:49:02

 

 


 

문제 설명

 

더보기

 

선거할 때마다 반드시 나타나는 신데렐라를 아시나요? 신데렐라는 예상과 다르게 경악할 정도로 뛰어난 결과를 보여준 캐릭터를 의미합니다. 신데렐라 수치는 티어와 예상 결과, 최종 결과와 같은 요소로 계산됩니다. 해당 수치에 따라 신데렐라가 결정됩니다.

선거가 시작되기 3주 전에 한 언론이 캐릭터 예상 순위를 발표합니다. 개표가 끝난 후 나오는 순위가 최종 결과가 됩니다. 예상 결과와 최종 결과 모두 티어가 있으며, 결과에 따른 티어는 아래 [표 1]과 같습니다.

 

 

결과에 나타나지 않은 캐릭터들은 순위 범위가 그 외에 속합니다. 티어 6을 제외하고 각 티어에서 순위가 가장 높으면 해당 티어에서 센터가 됩니다. 예를 들어, 17위를 획득한 캐릭터는 티어 2에서 순위가 가장 높습니다. 따라서 이 캐릭터는 티어 2에서의 센터가 됩니다.

캐릭터 c의 신데렐라 수치는 최종 티어가 6인 경우 0이고, 그렇지 않으면 아래와 같이 계산됩니다. 캐릭터 c의 예상 결과가 티어 x에 속하고, 최종 결과가 티어 y에 속할 때

 

  • x > y 경우
    • 10,000 * (x-y)입니다.
  • 최종 결과가 각 티어에서의 센터인 경우
    • 조건 1을 만족하는 경우 20,000입니다.
    • 그렇지 않은 경우 10,000입니다.
  • x가 1이 아니지만, y가 1인 경우
    • 아래 조건을 모두 만족하는 캐릭터의 수를 p라고 할 때 30,000 * p입니다.
      • 예상 결과가 캐릭터 c보다 좋았지만 최종 결과가 c보다 좋지 않습니다.
      • 예상 결과가 티어 1에 속했지만 최종 결과가 티어 1에 속하지 않습니다.

조건 1, 2, 3 중 만족하는 조건만 합산하여 계산됩니다. 예를 들어, 캐릭터 c의 예상 결과가 63위였지만 최종 결과가 20위였다면, 캐릭터 c의 신데렐라 수치는 아래와 같이 계산할 수 있습니다.

  1. 예상 결과가 티어 4에 속하지만 최종 결과는 티어 2에 속합니다.
  2. 최종 결과가 센터가 아닙니다.
  3. 최종 결과가 티어 1에 속하지 않습니다.

따라서, 캐릭터 c의 신데렐라 수치는 조건 1만 합산되어 20,000이 됩니다. 최종 결과가 80위 이내에 든 캐릭터 중 신데렐라 수치가 가장 높은 캐릭터들을 '신데렐라 후보'라고 하겠습니다. 이 후보들 중 순위가 가장 높은 캐릭터가 신데렐라가 됩니다. 신데렐라를 구해주세요.

 

 

입력 및 출력

 

더보기

입력

 

첫 줄에 예상 결과가 주어집니다. 이때, 1위부터 80위까지 순위가 높은 순서대로 {character_info}가 공백으로 구분되어 주어집니다.

두 번째 줄에 최종 결과가 주어집니다. 이때, 1위부터 80위까지 순위가 높은 순서대로 {character_info}가 공백으로 구분되어 주어집니다.

{character_info}는 아래와 같이 주어집니다.

{character_name} {group} {team}

{character_name}, {group}, {team}은 공백으로 구분되어 주어집니다. {group}은 아래와 같이 주어집니다.

Group {group_name}

Group과 {group_name}은 공백으로 구분되어 주어집니다. {team}은 아래와 같이 주어집니다.

Team {team_name}

Team과 {team_name}은 공백으로 구분되어 주어집니다.

{character_name}은 공백과 알파벳 대소문자와 숫자로만 주어지며 공백으로 시작하거나 끝나지 않습니다.
{character_name}에 연속으로 공백이 나오지 않습니다.
{group_name}과 {team_name}은 알파벳 대소문자와 숫자로만 주어집니다.

 

출력

 

첫 번째 줄에 신데렐라의 그룹명을, 두 번째 줄에 신데렐라의 팀 이름을, 세 번째 줄에 신데렐라의 캐릭터 이름을 출력해 주세요.

 

입력 예시

 

1 Group 1 Team 1 2 Group 1 Team 1 3 Group 1 Team 1 4 Group 1 Team 1 5 Group 1 Team 1 6 Group 1 Team 1 7 Group 1 Team 1 8 Group 1 Team 1 9 Group 1 Team 1 10 Group 1 Team 1 11 Group 1 Team 1 12 Group 1 Team 1 13 Group 1 Team 1 14 Group 1 Team 1 15 Group 1 Team 1 16 Group 1 Team 1 17 Group 1 Team 1 18 Group 1 Team 1 19 Group 1 Team 1 20 Group 1 Team 1 21 Group 1 Team 1 22 Group 1 Team 1 23 Group 1 Team 1 24 Group 1 Team 1 25 Group 1 Team 1 26 Group 1 Team 1 27 Group 1 Team 1 28 Group 1 Team 1 29 Group 1 Team 1 30 Group 1 Team 1 31 Group 1 Team 1 32 Group 1 Team 1 33 Group 1 Team 1 34 Group 1 Team 1 35 Group 1 Team 1 36 Group 1 Team 1 37 Group 1 Team 1 38 Group 1 Team 1 39 Group 1 Team 1 40 Group 1 Team 1 41 Group 1 Team 1 42 Group 1 Team 1 43 Group 1 Team 1 44 Group 1 Team 1 45 Group 1 Team 1 46 Group 1 Team 1 47 Group 1 Team 1 48 Group 1 Team 1 49 Group 1 Team 1 50 Group 1 Team 1 51 Group 1 Team 1 52 Group 1 Team 1 53 Group 1 Team 1 54 Group 1 Team 1 55 Group 1 Team 1 56 Group 1 Team 1 57 Group 1 Team 1 58 Group 1 Team 1 59 Group 1 Team 1 60 Group 1 Team 1 61 Group 1 Team 1 62 Group 1 Team 1 63 Group 1 Team 1 64 Group 1 Team 1 65 Group 1 Team 1 66 Group 1 Team 1 67 Group 1 Team 1 68 Group 1 Team 1 69 Group 1 Team 1 70 Group 1 Team 1 71 Group 1 Team 1 72 Group 1 Team 1 73 Group 1 Team 1 74 Group 1 Team 1 75 Group 1 Team 1 76 Group 1 Team 1 77 Group 1 Team 1 78 Group 1 Team 1 79 Group 1 Team 1 80 Group 1 Team 1
1 Group 1 Team 1 2 Group 1 Team 1 3 Group 1 Team 1 4 Group 1 Team 1 5 Group 1 Team 1 6 Group 1 Team 1 7 Group 1 Team 1 8 Group 1 Team 1 9 Group 1 Team 1 10 Group 1 Team 1 11 Group 1 Team 1 12 Group 1 Team 1 13 Group 1 Team 1 14 Group 1 Team 1 15 Group 1 Team 1 16 Group 1 Team 1 83 Group 1 Team 1 18 Group 1 Team 1 19 Group 1 Team 1 20 Group 1 Team 1 21 Group 1 Team 1 22 Group 1 Team 1 23 Group 1 Team 1 24 Group 1 Team 1 25 Group 1 Team 1 26 Group 1 Team 1 27 Group 1 Team 1 28 Group 1 Team 1 29 Group 1 Team 1 30 Group 1 Team 1 31 Group 1 Team 1 32 Group 1 Team 1 33 Group 1 Team 1 34 Group 1 Team 1 35 Group 1 Team 1 36 Group 1 Team 1 37 Group 1 Team 1 38 Group 1 Team 1 39 Group 1 Team 1 40 Group 1 Team 1 41 Group 1 Team 1 42 Group 1 Team 1 43 Group 1 Team 1 44 Group 1 Team 1 45 Group 1 Team 1 46 Group 1 Team 1 47 Group 1 Team 1 48 Group 1 Team 1 49 Group 1 Team 1 50 Group 1 Team 1 51 Group 1 Team 1 52 Group 1 Team 1 53 Group 1 Team 1 54 Group 1 Team 1 55 Group 1 Team 1 56 Group 1 Team 1 57 Group 1 Team 1 58 Group 1 Team 1 59 Group 1 Team 1 60 Group 1 Team 1 61 Group 1 Team 1 62 Group 1 Team 1 63 Group 1 Team 1 64 Group 1 Team 1 65 Group 1 Team 1 66 Group 1 Team 1 67 Group 1 Team 1 68 Group 1 Team 1 69 Group 1 Team 1 70 Group 1 Team 1 71 Group 1 Team 1 72 Group 1 Team 1 73 Group 1 Team 1 74 Group 1 Team 1 75 Group 1 Team 1 76 Group 1 Team 1 77 Group 1 Team 1 78 Group 1 Team 1 79 Group 1 Team 1 80 Group 1 Team 1

 

출력 예시

 

1
1
83

 

 


 

풀이

 

구현 문제 + 파싱 문제. 요즘 코테 보는 회사들이 하나쯤은 끼워넣을법한 문제인 것 같다. 조건에 맞는 점수를 구하여 그 점수가 제일 높고 실제 순위가 높은 사람을 출력하면 된다.

 

파싱 정규표현식에서 쪼금 해맸다... 익숙해지도록 노력하자. 실제 환경에선 쓸 일이 많을텐데.

 

풀이 코드

from collections import defaultdict
import re

def convert(string, score_dict) :
  s = re.findall(r'((\w*\s(?!Group))*(\w*)) Group (\w*) Team (\w*)\s?', string)
  for i, _s in enumerate(s) :
    score_dict[(_s[-2], _s[-1], _s[0])] = (i+1, i//16+1)

before = input().strip()
after = input().strip()
before_dict = defaultdict(lambda : (81, 6))
after_dict = defaultdict(lambda : (81, 6))

convert(before, before_dict)
convert(after, after_dict)
keys = set(before_dict.keys()).union(set(after_dict.keys()))
score_dict = dict()

for key in keys :
  bi, btier = before_dict[key]
  ai, atier = after_dict[key]
  if atier == 6 :
    continue
  score = 0
  cond_1 = False
  if btier > atier :
    score += 10000*(btier - atier)
    cond_1 = True
  if (ai - 1) % 16 == 0 :
    score += 20000 if cond_1 else 10000
  if btier != 1 and atier == 1 :
    p = 0
    for _key in keys :
      if before_dict[key] <= before_dict[_key] :
        continue
      if after_dict[key] >= after_dict[_key] :
        continue
      if before_dict[_key][1] == 1 and after_dict[_key][1] != 1 :
        p += 1
    score += 30000*p
  score_dict[key] = score

result = sorted(score_dict.keys(), key = lambda x : (-score_dict[x], after_dict[x]))
print(*result[0], sep = '\n')

풀이 완료!

Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.