https://www.acmicpc.net/problem/20055
deque의 rotate 이용 풀이
import sys
from collections import deque
input = sys.stdin.readline
# 입력 받기
N, K = map(int, input().split()) # N: 컨베이어 벨트 길이의 반, K: 내구도 0인 칸이 K개 이상이면 종료
durability = list(map(int, input().split())) # 컨베이어 벨트의 내구도
robots = deque([False] * N) # 로봇의 위치 (컨베이어 벨트 상단 부분만 관리)
belt = deque(durability) # 내구도와 벨트를 같이 관리
step = 0 # 진행 단계
while True:
step += 1 # 단계 증가
# 1️⃣ 벨트 이동 (벨트 회전)
belt.rotate(1) # 벨트 한 칸 회전
robots.rotate(1) # 로봇도 같이 이동
# 내리는 위치(N-1)에 도달한 로봇은 즉시 제거
robots[N - 1] = False
# 2️⃣ 로봇 이동 (오른쪽으로 한 칸씩 이동)
for i in range(N - 2, -1, -1): # N-2부터 0까지 거꾸로 이동
if robots[i] and not robots[i + 1] and belt[i + 1] > 0:
robots[i] = False # 기존 위치의 로봇 제거
robots[i + 1] = True # 새로운 위치로 로봇 이동
belt[i + 1] -= 1 # 내구도 감소
# 내리는 위치(N-1)에 도달한 로봇은 즉시 제거
robots[N - 1] = False
# 3️⃣ 로봇 올리기
if belt[0] > 0: # 올리는 위치(0번 칸)의 내구도가 1 이상이면 로봇 올리기
robots[0] = True
belt[0] -= 1 # 내구도 감소
# 4️⃣ 내구도가 0인 칸 개수 체크
if belt.count(0) >= K:
break
# 결과 출력
print(step)
rotate, slicing 이용하지 않은 풀이(시간, 메모리 더 효율적)
import sys
input = sys.stdin.readline
# 입력 받기
N, K = map(int, input().split()) # N: 컨베이어 벨트 길이의 반, K: 내구도 0인 칸이 K개 이상이면 종료
belt = list(map(int, input().split())) # 컨베이어 벨트의 내구도
robots = [False] * N # 로봇의 위치 (컨베이어 벨트 상단 부분만 관리)
step = 0 # 진행 단계
while True:
step += 1 # 단계 증가
# 1️⃣ 벨트와 로봇 회전
last_belt = belt[-1]
for i in range(2 * N - 1, 0, -1): # 이전꺼 가져오니까 맨앞은 남겨두기
belt[i] = belt[i - 1]
belt[0] = last_belt
for i in range(N - 1, 0, -1): # 로봇도 회전
robots[i] = robots[i - 1]
robots[0] = False
robots[-1] = False # 내리는 위치에서 로봇 제거
# 2️⃣ 로봇 이동 (오른쪽으로 한 칸씩 이동)
for i in range(N - 2, -1, -1): # N-2부터 0까지 거꾸로 이동.. N-1은 무조건 제거하니까 고려x
if robots[i] and not robots[i + 1] and belt[i + 1] > 0:
robots[i] = False
robots[i + 1] = True
belt[i + 1] -= 1
robots[-1] = False # 내리는 위치의 로봇 제거
# 3️⃣ 로봇 올리기
if belt[0] > 0 and not robots[0]: # 올리는 위치에 로봇이 없을 때만 올림
robots[0] = True
belt[0] -= 1 # 내구도 감소
# 4️⃣ 내구도가 0인 칸 개수 체크
if belt.count(0) >= K:
break
# 결과 출력
print(step)
리스트를 deque로 만들고 리스트명.rotate(이동원하는칸수) 하면 바로 되는거 몰랐다...
그냥 반복문 말고 슬라이싱을 이용하는 방법은
belt = [10, 20, 30, 40, 50]
belt = [belt[-1]] + belt[:-1] # 오른쪽으로 한 칸 이동
이렇게 하는 것이다!
알아두고 써먹어야겠다...
그리고 로봇 이동 시 인덱스 뒤쪽에 있는 것부터 먼저 해야하는 이유는 중복이동이 될 수 있기 때문이다!
0->1 이동, 다음 for문에서 1->2로 이동, 그다음에 2->3...이렇게 무한 이동가능하는 경우 발생 가능...
'백준' 카테고리의 다른 글
백준 11501. 주식 (0) | 2025.02.07 |
---|---|
백준 20006. 랭킹전 대기열 (0) | 2025.02.06 |
백준 1927. 최소 힙 (0) | 2025.02.03 |
백준 12919. A와 B 2 (0) | 2025.02.02 |
백준 20310. 타노스 (0) | 2025.02.02 |