ACM ICPC에 출전하고 싶다면 점수 계산법을 알아야 한다. 경시 대회에 참가한 팀의 순위는 우선 푼 문제의 개수가 많은 순으로, 그 다음으로는 시간 벌점(penalty time)이 적은 순으로 매겨진다. 이 둘을 모두 고려했는데도 동점 팀이 둘 이상이면 팀 멤버 수가 적은 쪽이 더 높은 순위를 차지할 수 있다. 

 

제출된 풀이 가운데 정답으로 판정받은 것이 하나라도 있으면 그 문제는 해결된 것으로 인정된다. 시간 벌점은 해당 문제에 대한 첫번째 정답이 제출될 때까지 걸린 시간으로 계산되며 정답이 나오기 전까지 제출된 오답이 있으면 한 개에 20분씩의 시간 벌점이 추가된다. 풀리지 않은 문제에 대해서는 시간 벌점이 전혀 적용되지 않는다.

 

입력

각 입력은 심사 큐의 스냅샷으로 구성되는데, 여기서는 1번부터 9번까지의 문제를 푸는 1번부터 100번까지의 경시 대회 참가 팀으로부터 입력된 내용이 들어있다. 각 줄은 세 개의 수와 경시 대회 문제 시간 L 형식의 글자 하나로 구성된다. L은 C, I, R, U 또는 E 라는 값을 가질 수 있는데 이 글자들은 각각 Correct(정답), Incorrect(오답), Clarification Request(확인 요청), Unjudged(미심사), Erroneous submission(제출 오류)을 의미한다. 마지막 세 개의 케이스는 점수에 영향을 미치치 않는다. 입력은 제출된 순서대로 입력된다.

 

출력

각 테스트 케이스에 대해 앞에서 설명한 순서에 의해 정렬된 점수표가 출력된다. 출력되는 각 줄에는 참가팀 번호, 그 팀이 푼 문제, 누적된 시간 벌점이 출력된다. 모든 경시 대회 참가 팀이 풀이를 제출하는 것은 아니므로 실제로 풀이를 제출한 팀의 결과만 표시한다. 그리고 두 개의 서로 다른 케이스에 대한 출력은 빈 줄로 구분한다.

 

예제


해설

문제를 묘하게 이해하기 힘들었다. "동점 팀이 둘 이상이면 팀 멤버 수가 적은 쪽이 더 큰 순위를 차지할 수 있다" 라는데 입력 어디에도 팀 멤버수가 정의되지 않았다. 이건 무시했다. 점수 집계를 파이썬의 딕셔너리를 사용하다보니, 딕셔너리의 정렬 방법에 대해서 공부가 필요했다. 다른 것은 평이하니 소스 코드를 보면 쉽게 이해가 될 것이다.

# Quiz 0015, Contest Score Board
# written by badsaram

import sys

class CScoreBoard(object):
    def __init__(self):
        self.history_board = []
        self.score_board = {}

    def input(self):
        ret = True

        while True:
            input_str = input()

            if (input_str == ""):
                ret = False
                break

            tokens = input_str.split(" ")

            try:
                team_id     = int(tokens[0])
                quiz_num    = int(tokens[1])
                proc_time   = int(tokens[2])
                result_type = tokens[3].strip().upper()

                if ((team_id <= 0) or (team_id > 100) or (quiz_num <= 0) or (quiz_num >= 10)):
                    ret = False
                    break

                self.history_board.append([team_id, quiz_num, proc_time, result_type])
            except:
                ret = False
                break

        return ret

    def test_input(self):
        self.history_board.append([1, 2, 10, 'I'])
        self.history_board.append([3, 1, 11, 'C'])
        self.history_board.append([1, 2, 19, 'R'])
        self.history_board.append([1, 2, 21, 'C'])
        self.history_board.append([1, 1, 25, 'C'])
        self.history_board.append([9, 1, 10, 'C'])
        self.history_board.append([9, 2, 30, 'C'])
        self.history_board.append([9, 3, 40, 'C'])
        self.history_board.append([4, 1, 10, 'C'])
        self.history_board.append([4, 2, 20, 'C'])

    def run(self):
        for history in self.history_board:
            if ((history[0] in self.score_board) == False):
                self.score_board[history[0]] = [ [], 0 ]

            if (history[3] == 'I'):
                self.score_board[history[0]][1] += 20
            elif (history[3] == 'C'):
                if ((history[1] in self.score_board[history[0]][0]) == False):
                    self.score_board[history[0]][0].append(history[1])

                self.score_board[history[0]][1] += history[2]
            else:
                pass

        d1 = sorted(self.score_board.items(), key = lambda x : (-len((x[1])[0]), (x[1])[1]))

        for item in d1:
            print("%d %d %d" % (item[0], len(item[1][0]), item[1][1]))

if __name__ == '__main__':
    obj = CScoreBoard()

    obj.input()
    #obj.test_input()
    obj.run()

+ Recent posts