728x90
시간 제한 1초, 메모리 제한 512MB
# 조건
- 길이가 N인 컨베이어 벨트가 있고, 길이가 2N인 벨트가 이 컨베이어 벨트를 위아래로 감싸며 돌고 있다.
- 벨트는 길이 1 간격으로 2N개의 칸으로 나뉘어져 있으며, 각 칸에는 아래 그림과 같이 1부터 2N까지의 번호가 매겨져 있다.
- 벨트가 한 칸 회전하면 1번부터 2N-1번까지의 칸은 다음 번호의 칸이 있는 위치로 이동하고, 2N번 칸은 1번 칸의 위치로 이동한다.
- i번 칸의 내구도는 Ai이다.
- 위의 그림에서 1번 칸이 있는 위치를 "올리는 위치", N번 칸이 있는 위치를 "내리는 위치"라고 한다.
- 컨베이어 벨트에 박스 모양 로봇을 하나씩 올리려고 한다.
- 로봇은 올리는 위치에만 올릴 수 있다.
- 언제든지 로봇이 내리는 위치에 도달하면 그 즉시 내린다.
- 로봇은 컨베이어 벨트 위에서 스스로 이동할 수 있다.
- 로봇을 올리는 위치에 올리거나 로봇이 어떤 칸으로 이동하면 그 칸의 내구도는 즉시 1만큼 감소한다.
- 컨베이어 벨트를 이용해 로봇들을 건너편으로 옮기려고 한다. 로봇을 옮기는 과정에서는 아래와 같은 일이 순서대로 일어난다.
- 벨트가 각 칸 위에 있는 로봇과 함께 한 칸 회전한다.
- 가장 먼저 벨트에 올라간 로봇부터, 벨트가 회전하는 방향으로 한 칸 이동할 수 있다면 이동한다. 만약 이동할 수 없다면 가만히 있는다.
- 로봇이 이동하기 위해서는 이동하려는 칸에 로봇이 없으며, 그 칸의 내구도가 1 이상 남아 있어야 한다.
- 올리는 위치에 있는 칸의 내구도가 0이 아니면 올리는 위치에 로봇을 올린다.
- 내구도가 0인 칸의 개수가 K개 이상이라면 과정을 종료한다. 그렇지 않다면 1번으로 돌아간다.
- 종료되었을 때 몇 번째 단계가 진행 중이었는지 구해보자. 가장 처음 수행되는 단계는 1번째 단계이다.
입력
- 첫째 줄에 N, K가 주어진다.
- 둘째 줄에는 A1, A2, ..., A2N이 주어진다.
출력
- 몇 번째 단계가 진행 중일 때 종료되었는지 출력한다.
# 접근 방법
- 시뮬레이션 문제는 주어진 조건을 잘 정리해서 그대로 함수화하여 구현 해주면 된다.
- 처음에 조건 정리해서 의사코드 짜는 것이 제일 중요한 듯..!
- 헷갈리지 말아야 할 것이, 벨트가 함께 회전하므로 내구도를 기록해준 리스트도 함께 회전하여야 한다.
- 가장 처음 수행되는 단계는 1번이므로 주의하여야 한다.
- 로봇 이동시 0번 자리는 0으로 없다고 변경해주어야 한다.
- 로봇 스스로 이동은 가장 먼저 올린 로봇부터 체크해주어야 하므로 리스트 뒤에서부터 체크한다.
- 내리는 위치는 내구도와 상관없이 로봇을 내리므로 주의해주어야 한다.
- 몇 번째 단계가 진행 중인지 체크하기 위하여 CNT 변수를 사용해준다.
- 1, 2, 3, 4번까지 완료된 후 cnt += 1
- 또한 종료 조건은 내구도가 0인 칸의 개수가 K개 이상일 때이므로, 0의 내구도가 발생한다면 실시간으로 체크해준다.
import sys
sys.stdin = open('input.txt')
input = sys.stdin.readline
# 로봇과 벨트 함께 회전
def rotate_with_robot():
# 벨트 회전
# 마지막 내구도 저장해준 후 1 ~ 마지막을 0 ~ 마지막 앞에까지로 복사해준다.
l_belt = belt[-1]
belt[1:] = belt[0:2*N-1]
belt[0] = l_belt
# 로봇은 1 ~ 마지막을 0~마지막 앞 까지만 복사해주면 된다.
robots[1:] = robots[0:N-1]
robots[0] = 0
# 로봇 스스로 이동
def robot_move():
# 가장 먼저 올라간 로봇이 이동해야되므로 뒤에서부터 체크
for i in range(N-1, -1, -1):
if robots[i]:
# 로봇이 내리는 위치라면 내리고
if i == N-1:
robots[i] = 0
else:
# 내리는 위치가 아니라면 로봇이 없고, 벨트 내구도가 0보다 많다면 이동
# 이동 후에는 내구도를 -1 해주어야 한다.
if not robots[i+1] and belt[i+1]:
robots[i] = 0
robots[i+1] = 1
belt[i+1] -= 1
# 로봇 올리기
def raise_robot():
if belt[0]:
robots[0] = 1
belt[0] -= 1
N, K = map(int, input().split())
belt = [*map(int, input().split())]
robots = [0]*N
cnt = 0
zero_cnt = belt.count(0)
# 내구도가 0개 이하일 때까지 반복문 진행한다.
while zero_cnt < K:
cnt += 1
# 로봇과 벨트 함께 회전
rotate_with_robot()
# 로봇 스스로 이동
robot_move()
#올리는 위치의 내구도가 0이 아니라면 로봇 올려주기
raise_robot()
zero_cnt = belt.count(0)
print(cnt)
728x90
'ALGORITHM > 정렬, 탐색,구현' 카테고리의 다른 글
[백준 12919번] 파이썬 - A와 B 2 (0) | 2023.06.27 |
---|---|
[백준 1017번] 파이썬 - 소수 쌍 (1) | 2023.06.14 |
[백준 16234번] 파이썬 - 인구 이동 (0) | 2023.06.08 |
[백준 14890번] 파이썬 - 경사로 (0) | 2023.06.08 |
[백준 16566번] 파이썬 - 카드 게임 (0) | 2023.05.06 |