백준 “그래픽스 퀴즈” 문제를 풀어보았습니다.
여기를 누르면 건너뛸 수 있습니다.
문제
오늘은 기초컴퓨터그래픽스의 퀴즈가 있는 날이다. 기다란 교실 안에는 N개의 책상이 한 줄로 늘어서 있는데, 각 책상당 두 명의 학생이 앉도록 되어있다.
모든 학생들은 그래픽스를 열심히 공부했지만, 말도 안되는 난이도에 질려 포기하고 말았다. 한편 교수님은 각 학생들의 얼굴만 보고도 이 학생이 받아야 할 그레이드를 정확히 알아낼 수 있다.
교수님은 그래픽스 과목을 가르치는 만큼 자신의 미적 감각을 살리기 위해 각 그레이드를 다른 색을 이용해서 표시한다(예를 들어 A를 빨강으로 칠하면, B,C,D는 빨강으로 표시하지 않는다).
또, 퀴즈의 방식은 교수님이 수업이 시작할 때 어떤 두 책상을 선택하고, 두 책상과 그 사이에 있는 모든 책상에서 각각 한 명씩 지목해서 질문을 하고, 학생의 대답을 듣는 것이다.
오늘 교수님은 바쁜 나머지 한 가지 색의 색연필만 가지고 왔고, 결국 자신의 미학을 지키기 위해 퀴즈에서 지목한 모두에게 같은 그레이드를 주려고 한다. 교수님이 채점할 수 있는 학생의 수는 최대 몇 명일까?
입력
입력의 첫 번째 줄에는 정수 N이 주어진다(1 ≤ N ≤ 100,000).
다음 N개의 줄에는 i번째 책상에 앉은 두 학생이 받아야 할 그레이드 Ai와 Bi(1 ≤ Ai, Bi ≤ 5)가 주어진다.
출력
교수님이 한 가지 색만을 이용해 채점할 수 있는 최대 학생 수와 그때의 그레이드를 출력한다.
만약 답이 여러 가지라면, 가장 작은 그레이드를 출력한다.
예제 입력 1
1
1 5
예제 출력 1
1 1
예제 입력 2
3
3 5
4 5
1 3
예제 출력 2
2 5
예제 입력 3
4
2 1
3 2
5 3
2 5
예제 출력 3
2 2
Solution
[문제 이해]
처음보는 유형의 문제로 검색을 통해 누적 합(Prefix Sum)
알고리즘으로 풀이를 진행했습니다.
- 입력값 2개 중에 1개 임의로 선택하여 누적 합을 계산
→ 받을 등급이 같은 학생 수를 누적 합으로 계산 - 누적 합의 수가 동일하면, 등급이 낮은게 우선
이해한 내용을 바탕으로 코드를 작성했습니다.
[코드]
from collections import defaultdict
import sys
input = sys.stdin.readline
def solution():
n = int(input())
grades = defaultdict(dict)
for i in range(n+1):
for j in range(6):
grades[i][j] = 0
max_num = 0
max_grade = 0
# dictionary 구조로 누적합 사용
def prefix_sum(i, num):
nonlocal max_num, max_grade, grades
grades[i][num] = grades[i-1][num] + 1
if grades[i][num] > max_num:
max_num = grades[i][num]
max_grade = num
elif grades[i][num] == max_num and max_grade > num:
max_grade = num
for i in range(1, n+1):
a, b = map(int, input().split())
prefix_sum(i, a)
if a != b:
prefix_sum(i, b)
print(max_num, max_grade)
solution()
아래의 코드는 다른 사람의 풀이로, 리스트 자료구조를 사용하여 처리 효율을 높힌 케이스입니다.
[처리 효율이 좋은 코드]
# 처리 효율 좋아서 추가
import sys
n = int(sys.stdin.readline())
res = dict().fromkeys([i for i in range(1, 6)])
for i in res:
res[i] = []
arr = []
for _ in range(n):
arr.append(list(map(int, sys.stdin.readline().split())))
for k in range(1, 6):
size = 0
for i in range(n):
if arr[i][0] == k or arr[i][1] == k:
size += 1
else:
res[k].append(size)
size = 0
if size > 0:
res[k].append(size)
ans = []
for i in res:
ans.append((i, max(res[i])))
ans.sort(key=lambda x : (-x[1], x[0]))
print(ans[0][1], ans[0][0])
[과정]
누적 합 알고리즘을 먼저 이해하기 위해서 예제를 작성해봤습니다.
그리고 2개의 입력중 임의의 값이라는 처리를 위해서 dictionary 구조를 사용하여 누적 합 알고리즘을 작성했습니다.