728x90
반응형

백준 20055번 컨베이어 벨트 위의 로봇 문제를 먼저 한번 읽어보시고 오시길 바랍니다.

20055번: 컨베이어 벨트 위의 로봇

길이가 N인 컨베이어 벨트가 있고, 길이가 2N인 벨트가 이 컨베이어 벨트를 위아래로 감싸며 돌고 있다. 벨트는 길이 1 간격으로 2N개의 칸으로 나뉘어져 있으며, 각 칸에는 아래 그림과 같이 1부

www.acmicpc.net

문제 이해가 가시나요? 저는 무슨 말인지 도통 이해가 안 가더라고요..?

하지만 대부분 문제를 한번 읽고 구글링을 통해서 이 글을 접하셨을 가능성이 크겠죠?
아무래도 삼성 기출문제를 변형하는 과정에서 문제 설명이 이상하게 된 거 같습니다.
문제에서 가장 헷갈렸던 부분과 필요 없는 문장을 알려드릴 테니까 아래의 내용을 끝까지 읽고 다시 문제를 풀어보시길 바랍니다.

일단 차근차근 문제를 요약해봤습니다.

1번 칸 => 올리는 위치, N번 칸 => 내리는 위치
로봇은 올리는 위치(1번 칸)에만 올릴 수 있고, 내리는 위치(n자리)에 도달하면 즉시 내린다.
로봇은 컨베이어 벨트 위에서 스스로 이동할 수 있다. ----?
로봇을 올리는 위치에 올리거나 로봇이 어떤 칸으로 이동하면 그 칸의 내구도는 1 감소한다.
로봇이 이동하기 위해서는 이동하려는 칸에 로봇이 없으며, 그 칸의 내구도가 1 이상 남아 있어야 한다.

로봇을 건너편으로 옮기려고 한다.
1. 벨트가 각 칸 위에 있는 로봇과 함께 한 칸 회전한다.
2. 가장 먼저 벨트에 올라간 로봇부터, 벨트가 회전하는 방향으로 한 칸 이동할 수 있다면 이동한다. 만약 이동할 수 없다면 가만히 있는다.
3. 올리는 위치에 있는 칸의 내구도가 0이 아니면 올리는 위치에 로봇을 올린다.
4. 내구도가 0인 칸의 개수가 k개 이상이라면 과정을 종료한다. 그렇지 않으면 1번으로 돌아간다.


종료되었을 때 몇 번째 단계가 진행 중이었는지 구해라 가장 처음 수행되는 단계는 1번째 단계이다.

문제를 풀고 난 뒤, 위에 요약본에서 필요 없는 말들을 지우고, 좀 더 보충할 말들을 덧붙여보겠습니다.

1번 칸 => 올리는 위치, N번 칸 => 내리는 위치
로봇은 올리는 위치(1번 칸)에만 올릴 수 있고, 내리는 위치(n자리)에 도달하면 즉시 내린다.
로봇은 컨베이어 벨트 위에서 스스로 이동할 수 있다.
로봇을 올리는 위치에 올리거나 로봇이 어떤 칸으로 이동하면 그 칸의 내구도는 1 감소한다.
로봇이 이동하기 위해서는 이동하려는 칸에 로봇이 없으며, 그 칸의 내구도가 1 이상 남아 있어야 한다.

로봇을 건너편으로 옮기려고 한다.
1. 벨트가 각 칸 위에 있는 로봇과 함께 한 칸 회전한다. => 내구도 회전 + 로봇 회전(처음에 올려진 로봇은 없다.)
2. 가장 먼저 벨트에 올라간 로봇부터, 벨트가 회전하는 방향으로 한 칸 이동할 수 있다면 이동한다. 만약 이동할 수 없다면 가만히 있는다.
3. 올리는 위치에 있는 칸의 내구도가 0이 아니면 올리는 위치에 로봇을 올린다.
4. 내구도가 0인 칸의 개수가 k개 이상이라면 과정을 종료한다. 그렇지 않으면 1번으로 돌아간다.


종료되었을 때 몇 번째 단계가 진행 중이었는지 구해라 가장 처음 수행되는 단계는 1번째 단계이다

가장 헷갈렸던 말인 '로봇은 컨베이어 벨트 위에서 스스로 이동할 수 있다.' 이 문장은 문제를 푸는 데 있어서 필요가 없는 말인 것 같습니다.
이 문장만 빼도 문제를 이해하는데 조금은 더 편하지 않을까 싶습니다.
그럼 밑에 풀이를 남길 테니 다시 문제로 돌아가 먼저 한번 직접 풀어보시는 것을 추천드립니다.
이 문제는 삼성 기출치고는 쉬운 편이니 꼭 직접 푸셔서 자신감을 얻으셨으면 좋겠습니다.

풀이 (아직 안 푼 사람 눈감아...!)

import sys
from collections import deque
sys.stdin = open("input.txt", "r")

n, k = map(int, input().split())
belt = deque(list(map(int, input().split())))
robot = deque([0]*n)
res = 1

while True:
	#1
	belt.rotate(1)
	robot.rotate(1)
	robot[-1] = 0 #로봇이 내려가는 부분이니 0
	#2
	if robot: #로봇이 존재하면
		for i in range(n-2, -1, -1): #로봇 내려가는 부분 인덱스 i-1 이므로 그 전인 i-2부터
			if robot[i] == 1 and robot[i+1] == 0 and belt[i+1] >= 1: #다음 칸의 로봇이 없고, 내구도가 1이상
				robot[i+1] = 1
				robot[i] = 0
				belt[i+1] -= 1
		robot[-1] = 0 #이 부분도 로봇 out -> 0임
	#3
	if robot[0] == 0 and belt[0]>=1: #올리는 위치에 로봇이 없고,칸의 내구도 0이 아니면
		robot[0] = 1
		belt[0] -= 1
	#4
	if belt.count(0) >= k:
		break

	res += 1

print(res)

배울 점

  • deque의 rotate
  • 컨베이어 벨트는 2n만큼 회전하지만, 로봇은 n자리에서 out ⇒ n만큼만 회전하면 된다.
  • 각 단계에서 내리는 자리에서 내렸는지 확인 필수
728x90
반응형
  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기