BOJ 1713 후보 추천하기

LONGNEW·2022년 1월 13일
0

BOJ

목록 보기
292/333

https://www.acmicpc.net/problem/1713
시간 2초, 메모리 128MB
input :

  • N (1 ≤ N ≤ 20)
  • 총 추천 횟수 (1 <= 추천 횟수 <= 1,000)
  • 학생의 번호 (1 <= 번호 <= 100)

output :

  • 최종 후보의 학생 번호를 증가하는 순서대로 출력

조건 :

  • 학생들이 추천을 시작하기 전에 모든 사진틀은 비어있다.

  • 추천받은 학생의 사진이 반드시 사진틀에 게시되어야 한다.

  • 비어있는 사진틀이 없는 경우 : 추천 받은 횟수가 가장 적은 학생의 사진을 삭제하고, 추천받은 학생의 사진을 게시한다.

  • 추천 받은 횟수가 가장 적은 학생이 두 명 이상일 경우 : 그러한 학생들 중 게시된 지 가장 오래된 사진을 삭제한다.

  • 현재 사진이 게시된 학생이 다른 학생의 추천을 받은 경우에는 추천받은 횟수만 증가시킨다.

  • 사진틀에 게시된 사진이 삭제되는 경우에는 해당 학생이 추천받은 횟수는 0으로 바뀐다.


사진은 꼭 사진틀에 게시
모두 게시 된 경우에는 특정 학생의 사진을 삭제한 후에 추가
삭제되는 경우 추천 횟수는 0으로 초기화

사진틀에 게시되어 있을 때 이 사진의 추천 횟수를 업데이트하는 부분에서 오류가 있었다.
해당 사진의 최근 추천 날짜가 아닌 첫 게시일을 가지고 있어야 한다.

실버 2 문제인데 생각보다 많은 자료구조를 써야 해서 시간제한이 빡세면 어렵지 않을까 싶다.

다음 풀이

  1. 사진틀의 삭제 경우 (추천 횟수, 오래된 사진)
  2. 동일한 후보의 추천 경우

횟수가 가장 적은, 그 중 가장 오래된을 찾으려면 heapq뿐으로는 불가능 하다. lambda 정렬을 통해 2가지 조건을 넣는 것이 좋을 것 같다. 동일한 후보는 인덱스를 찾아서 꺼낸 후 업데이트를 하는 것이 좋다.

마지막에 정렬이 필요한 것도 잊으면 안 된다.

3
14
2 1 4 3 5 6 2 7 2 100 100 54 54 50
출력 : 50 54 100

이 예외 케이스로 오래된 날짜를 찾을 수 있다.

import sys

n = int(sys.stdin.readline())
m = int(sys.stdin.readline())
data = list(map(int, sys.stdin.readline().split()))

q, cnt, visit = [], [0] * 101, [0] * 101
for day in range(len(data)):
    person = data[day]
    length = len(q)

    if visit[person]:
        q.sort(key=lambda x:(-x[0], -x[1]))
        for i in range(length):
            if q[i][2] == person:
                break

        temp_cnt, temp_day, temp_person = q.pop(i)
        cnt[person] += 1
        q.append((cnt[person], temp_day, person))
        continue

    if length == n:
        q.sort(key=lambda x: (-x[0], -x[1]))
        temp_cnt, temp_day, temp_person = q.pop()
        visit[temp_person] = 0
        cnt[temp_person] = 0

    cnt[person] += 1
    visit[person] = 1
    q.append((cnt[person], day, person))

ans = []
for a, b, c in q:
    ans.append(c)

ans.sort()
print(*ans)

0개의 댓글