목차
1. 문제
2. 입출력 예시
입력 예시 | 출력 예시 |
---|---|
2 5 3 2 1 4 4 1 2 3 5 5 7 3 6 7 3 4 2 1 4 5 7 2 5 6 1 | 4 3 |
3. 문제 풀이
이 문제는 어찌보면 매우 간단하게 해결가능하나, 시간초과
를 고려해야 하기 때문에 골치아픈 문제이다. 이 문제 흐름의 핵심은 정렬 후 값의 크기 비교이다. 서류심사 순위와 면접심사 순위가 주어지는데, 다른 사람들과 비교하였을 때 두 개 순위 모두 뒤처질 경우 탈락하는 방식이다. 즉, 둘 중 하나는 다른 사람들보다 높아야하므로 이를 알아보기 쉽게 서류심사 순위를 기준으로 오름차순 정렬을 해주어야 한다.
주어진 예시를 통해서 확인해보자. 먼저 5명인 경우 [(3, 2), (1, 4), (4, 1), (2, 3), (5, 5)]
가 주어진다. 이를 서류심사 순위를 기준으로 오름차순 정렬을 해보면 [(1, 4), (2, 3), (3, 2), (4, 1), (5, 5)]
이며, 표로 나타내보면 아래와 같다.
서류심사 순위 | 면접심사 순위 |
---|---|
1 | 4 |
2 | 3 |
3 | 2 |
4 | 1 |
5 | 5 |
위 예시는 매우 간단하게 나와있기 때문에 누가 탈락할 것인지(5, 5)
를 한 눈에 알아볼 수 있다. 주어진 예시 중 7명인 경우의 예시를 통해 자세히 알아보도록 하자. 이 경우도 마찬가지로 서류심사 순위를 기준으로 오름차순 정렬을 하면 아래 표와 같다.
순서 | 서류심사 순위 | 면접심사 순위 |
---|---|---|
첫 번째 | 1 | 4 |
두 번째 | 2 | 5 |
세 번째 | 3 | 6 |
네 번째 | 4 | 2 |
다섯 번째 | 5 | 7 |
여섯 번째 | 6 | 1 |
일곱 번째 | 7 | 3 |
위의 표를 통해 면접심사 순위를 비교하면 아래와 같은 결과를 확인할 수 있다. 서류심사 순위의 경우 오름차순 정렬을 해주었기 때문에 이전 순서의 사람과 비교하였을 때 낮을 수 밖에 없으며, 면접심사 순위는 비교했던 사람들 중 가장 높은 순위를 기준으로 계속해서 비교해야 한다.
순서 | 면접심사 순위 비교 대상 | 서류심사 순위 비교 | 면접심사 순위 비교 결과 | 합격 결과 |
---|---|---|---|---|
첫 번째 | 4 | 가장 높음 | 비교할 필요 없음 | 합격 |
두 번째 | 4 | 낮음 | 4순위 >5순위 : 낮음 |
불합격 |
세 번째 | 4 | 낮음 | 4순위 > 6순위 : 낮음 |
불합격 |
네 번째 | 4 | 낮음 | 4순위 < 2순위 : 높음 |
합격 |
다섯 번째 | 2 | 낮음 | 2순위 > 7순위 : 낮음 |
불합격 |
여섯 번째 | 2 | 낮음 | 2순위 < 1순위 : 높음 |
합격 |
일곱 번째 | 여섯 번째 | 낮음 | 1순위 > 3순위 : 낮음 |
불합격 |
이러한 논리를 수행하기 위하여 순서를 세워보았다.
- 테스트 케이스의 수량(
T
)을 입력 받으며,T
만큼 반복하는 동안 아래의 동작을 수행한다.- 지원자의 수(
N
)를 입력 받으며, 지원자의 수 길이 만큼 숫자 0을 요소로 지닌 리스트(P
)를 생성한다. - 지원자의 수 만큼 지원자의 면접심사 순위와 서류심사 순위를 입력받으며, 입력 받은 문자열은 공백을 기준으로 나누어 준다.
- 서류심사 순위(
x
)를 기준으로 오름차순 정렬과 동시에 면접심사 순위(y
)를 별도로 추출하기 위하여P[x - 1]
를 면접심사 순위로 변경한다. - 첫 번째를 제외한 모든 사람들의 면접심사 순위가 이전 사람의 면접심사 순위보다 낮아야 합격하므로 최상위 면접심사 순위(
MIN
)를 첫 번째 사람의 면접심사 순위로 초기화하며, 첫 번째 사람은 무조건 합격이므로 합격자 수(CNT
)를 1로 초기화한다. - 첫 번째 사람을 제외한 나머지 모든 사람의 수 만큼 반복하며, 해당 사람의 면접심사 순위(
p
)가 최상위 면접심사 순위(MIN
) 보다 높을 경우(p < MIN
) 합격자 수를 증가(CNT += 1
) 시키고, 최상위 면점심사 순위(MIN
)를 해당 사람의 면접심사 순위(p
)로 초기화한다. - 반복이 끝나면 합격자 수(
CNT
)를 출력 후 테스트케이스 수량 만큼 이를 다시 반복한다.
- 지원자의 수(
- 테스트 케이스 수량 만큼의 반복이 끝나면 프로그램을 종료한다.
이를 코드로 나타내면 아래와 같다.
T = int(input())
for _ in range(T):
N = int(input())
P = [0 for _ in range(N)]
for i in range(N):
x, y = map(int, input().split())
P[x-1] = y
MIN = P[0]
CNT = 1
for p in P[1:]:
if p < MIN:
CNT += 1
MIN = p
print(CNT)
그러나, 위의 코드를 제출하면 시간초과
라는 결과를 받게 된다. 이를 해결하기 위하여 pop
, queue
등을 사용하였음에도 불구하고 결과는 동일했다. 다른 사람들이 작성해놓은 코드를 통해 내가 작성한 코드를 검토하던 중 새로운 입력 방식에 대해 알게 되었다. 기존에 내가 알던 입력 방식은 input()
이 전부였으나, 새로 알게된 방식은 sys.stdin.readline()
이며, 수정한 코드는 아래와 같다.
import sys
T = int(sys.stdin.readline())
for _ in range(T):
N = int(sys.stdin.readline())
P = [0 for _ in range(N)]
for i in range(N):
x, y = map(int, sys.stdin.readline().split())
P[x-1] = y
MIN = P[0]
CNT = 1
for p in P[1:]:
if p < MIN:
CNT += 1
MIN = p
print(CNT)
위의 코드로 수정 후 다시 제출하였더니 맞았습니다
라는 결과를 받았으며, 메모리 33,412 KB
, 시간 2,496 ms
가 소요되었다. input()
과 sys.stdin.readline()
은 각각 어떠한 방식으로 동작하길래 구현 시간에 있어서 시간 차이가 발생하는걸까? 이 궁금증은 조금 더 검색 후 공부한 다음에 정리하여 포스팅하도록 하겠다.
'Algorithm > Baekjoon' 카테고리의 다른 글
Baekjoon #1339 - 단어 수학 (0) | 2021.03.24 |
---|---|
Baekjoon #10162 - 전자레인지 (0) | 2021.03.24 |
Baekjoon - #2217 - 로프 (0) | 2021.03.23 |
Baekjoon #1541 - 잃어버린 괄호 (0) | 2021.03.22 |
Baekjoon #5585 - 거스름돈 (0) | 2021.03.21 |