문제 접근 및 공부 내용, 풀이는 모두 하단 코드에 "주석"으로 포함되어 있으니 참고해주세요.
문제 유형 보기
https://www.acmicpc.net/problem/2164
풀이
# 1차 풀이, 최적화 안됨
from collections import deque
import sys
input = sys.stdin.readline
# 입력 : 카드 개수를 의미하는 정수 N (1 <= N <= 50만)
# 출력 : 남게 되는 카드의 번호 정수
# 1번 카드가 제일 위에, N번 카드가 제일 아래.
# ex. N = 3일 때
# 1
# 2
# 3
# 대충 1 2 3으로 생각하면 될듯.
# 아래 동작을, 카드가 한 장 남을 때까지 반복
# 1. 제일 위에 있는 카드를 바닥에 버림
# 2. 제일 위에 있는 카드를 제일 아래에 있는 카드 밑으로 옮김
# ex. N = 3일 때
# 1. 1 2 3 4 5 -> 1 2 3 4
# 2. 1 2 3 4 -> 2 3 4 1
# 큐를 써서 풀어야 한다고 판단한 근거)
# '제일 위에 있는 카드를 바닥에 버린다'
# '제일 위에 있는 카드를 제일 아래에 있는 카드 밑으로 옮긴다'
# 와 같이, ""양 끝단에서 데이터의 삽입과 추출이 이루어지고 있기에???""
# 따라서, 큐를 써서 풀어야겠다고 판단하는 것이다.
# 그리고 당연히 중간 조회보단 삽입 추출이 자주 일어나니
# 리스트가 아닌 덱을 써야함.
N = int(input())
# 카드 상태 초기화
# 큐의 앞에 있을수록 문제에선 위에 있는 카드라고 생각.
# queue = deque()
# for number in range(1, N + 1):
# queue.append(number)
queue = deque(range(1, N + 1))
# 위 코드로 빠르게 초기화 가능.
# range 외에도 리스트, 문자열, 튜플, 셋 등의 iterator로 초기화 가능함.
# list()로 리스트 초기화해주는 것과 똑같이 생각하면 됨.
# 카드가 한 장 남을 때까지 반복
# for _ in range(N - 1):
while len(queue) > 1:
# 1. 제일 위에 있는 카드 버리기
queue.popleft()
# 2. 제일 위에 있는 카드를 제일 아래로 옮기기
queue.append(queue.popleft())
# print(*queue)
print(queue[0])
# 시간복잡도는 O(n * 1) = O(n) 정도로 보면 될듯.
# 입력이 최대 50만이니, 시간복잡도 측면에서도 OK!!
# 면접에서, 왜 덱으로 풀었냐고 묻는다면?
# 만약 queue로 풀었다면,
# 문제를 보니, 맨 위의 카드를 버리는 것과 맨 위의 카드를 아래로 옮기는 동작이
# 각각 pop(0)가 2번씩 포함되어 있다.
# 근데, 만약 list로 queue를 구현해 풀었다면,
# N이 50만까지 가능하므로, 최악의 경우로 50만장의 카드가 들어왔을 경우
# pop(0)은 대략 O(n)의 시간복잡도를 가지기에 50만번의 단위 연산이 합니다.
# pop(0)가 2개 있기에 반복문이 한 번 돌 때마다 거의 100만번 이상의 단위 연산이 소요됩니다.
# 해당 반복문이 50만번 반복될 것이므로,
# 100만 * 50만 = 5000만으로, 거의 5000만번의 단위 연산이 일어납니다.
# 그런데, 문제의 시간 제한이 2초이면 대략적으로 2억번의 단위 연산내에 풀어야 안정적이므로,
# 그런데, 덱의 경우는 pop(0) 대신 popleft()로 O(1)만에 해당 연산이 가능하므로,
# 약 O(n)의 시간복잡도로 해당 문제가 해결이 가능합니다.
# 따라서, 덱을 사용하였습니다.
250218 재풀이
from collections import deque
import sys
input = sys.stdin.readline
# n장 카드 1~n 번호
# 아래 동작을 카드가 한 장 남을 때까지 반복
# 1. 제일 위에 있는 카드를 버림
# 2. 제일 위에 있는 카드를 제일 아래에 있는 카드 밑으로 옮김.
# 이거 덱(큐) 쓰는 문제네!
n = int(input())
queue = deque(range(1, n + 1))
for _ in range(n - 1):
# 1. 제일 위에 있는 카드 버림
queue.popleft()
# 2. 제일 위에 있는 카드 제일 밑으로 옮김
queue.append(queue.popleft())
print(queue[0])
'Algorithms and Languages > 파이썬 알고리즘 문제풀이' 카테고리의 다른 글
[Python/DailyAlgo] 28. 그래프 탐색 (0) | 2025.02.18 |
---|---|
[Python/백준] 9012. 괄호 (0) | 2025.02.18 |
[Python/백준] 10773. 제로 (0) | 2025.02.18 |
[Python/DailyAlgo] 81. 스택, 82. 큐, 83. 덱 (0) | 2025.02.18 |
[Python/백준] 9291. 스도쿠 채점 (0) | 2025.02.18 |