![](https://img1.daumcdn.net/thumb/R750x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FRRzJS%2FbtrmbmnPdL4%2FogmAK2DoDRZmF9KxDjWHBK%2Fimg.png)
[백준] 20055(파이썬) - 컨베이어 벨트 위의 로봇
resilient
·2021. 11. 26. 10:46
728x90
반응형
https://www.acmicpc.net/problem/20055
20055번: 컨베이어 벨트 위의 로봇
길이가 N인 컨베이어 벨트가 있고, 길이가 2N인 벨트가 이 컨베이어 벨트를 위아래로 감싸며 돌고 있다. 벨트는 길이 1 간격으로 2N개의 칸으로 나뉘어져 있으며, 각 칸에는 아래 그림과 같이 1부
www.acmicpc.net
- 이 문제를 읽고 처음 든 생각은 그냥 일단 하라는 대로 해보자 였습니다ㅎㅎ
일단 큐 형식을 한 칸씩 돌리면서 구현하는 경우에 deque 라이브러리에 있는 rotate함수를 이번 문제를 풀면서 알게 되었습니다.(아주 유용한 함수 더라고요)
알고리즘을 풀면서 느낀 건 파이썬에서 리스트는 그다지 좋지 않은 비효율적인 자료형이라는 것입니다.
위 사항들을 고려하면서 설명을 적어보겠습니다. - 먼저 while을 이용해서 # 내구도가 0인 칸의 개수가 K개 이상이라면 과정을 종료한다. 의 조건을 만족시켜줍니다.
- 그리고 belt 도 한 칸씩 돌리고 로봇이 있는 위치를 나타내는 0이 들어간 queue 자료형인 robot 또한 자리를 이동시켜줍니다. 한 칸씩 돌렸으면 robot의 맨 마지막은 로봇이 있던 없던 내리는 칸이기 때문에 0을 넣어줍니다.
- 다음은 컨베이어 벨트위에 로봇이 하나라도 있을 경우, for문을 돌리면서 현재 위치에는 로봇이 있고 만약 다음 자리에 로봇이 없을 경우, 그리고 belt에서 해당 자리의 내구성이 1 이상일 경우, 로봇을 움직여 줍니다.
- 움직여 준 뒤에는, 로봇이 한칸 씩 이동하였으므로 robot의 맨 마지막에 0을 넣어줍니다.
- 위 과정들이 끝나면, robot의 맨 앞에는 올리는 위치이므로 만약에 로봇이 없고, 내구성이 1 이상일 경우, 로봇을 올리는 위치에 올려줍니다.
- 마지막으로 위 모든 과정들이 끝날 때마다 ans 변수에 1씩 더해서 얼마나 반복되었는지 결과를 출력해줍니다.
import sys
input = sys.stdin.readline
from collections import deque
n,k = map(int,input().split())
# 벨트가 각 칸 위에 있는 로봇과 함께 한 칸 회전한다.
# 가장 먼저 벨트에 올라간 로봇부터, 벨트가 회전하는 방향으로 한 칸 이동할 수 있다면 이동한다. 만약 이동할 수 없다면 가만히 있는다.
# 로봇이 이동하기 위해서는 이동하려는 칸에 로봇이 없으며, 그 칸의 내구도가 1 이상 남아 있어야 한다.
# 올리는 위치에 있는 칸의 내구도가 0이 아니면 올리는 위치에 로봇을 올린다.
# 내구도가 0인 칸의 개수가 K개 이상이라면 과정을 종료한다. 그렇지 않다면 1번으로 돌아간다.
ans = 0
belt = deque(map(int,input().split()))
# 로봇위치는 n개다 위에만 세면 된다 아래는 어차피 로봇 못 둔다.
robot = deque(list([0]*n))
while belt.count(0) < k:
#한 칸씩 돌리기
belt.rotate(1)
robot.rotate(1)
robot[-1] = 0
if sum(robot) > 0 :
for i in range(n-2,-1,-1):
# robot[i] 가 0 이면 로봇이 없기 때문에 이동해줄 수 있음
# 이동해주면 그자리는 내구성 -1 해주면 된다.
if robot[i] == 1 and robot[i+1] == 0 and belt[i+1]>=1:
robot[i+1] = 1
robot[i] = 0
belt[i+1] -= 1
robot[-1] = 0
if robot[0] == 0 and belt[0]>=1:
robot[0] = 1
belt[0] -= 1
ans += 1
print(ans)
반응형