티스토리 뷰

반응형

https://www.acmicpc.net/problem/20055

 

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

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

www.acmicpc.net

 

난이도 : 실버 1

 

문제 이해를 못해서 지문을 몇 번 읽었는지 모르겠습니다.

제가 헷갈렸던 부분을 위주로 설명하겠습니다.

이 그림을 처음에 컨베이어 벨트를 위에서 바라본 모습으로 착각했네요. 

이런 형식의 그림으로 착각해서 시작부터 꼬였습니다.

 

이런 식으로 컨베이어 벨트를 옆에서 바라본 것으로 생각하면 이해하기 쉽습니다.

위 그림의 경우 1~5가 상단에 위치하고 있고 1이 올라가는 위치, 5가 내려가는 위치입니다. 즉, 로봇이 5에 위치하면 로봇이 내려갑니다. 5번에서 로봇이 이동하거나 벨트가 회전하여 떨어지는 구조가 아닙니다. 이 조건 때문에 몇 시간을 버렸는지 모르겠네요.

 

저는 2*n 크기의 배열을 통해 풀었습니다. 다양한 방법이 있겠지만 left와 right를 이용하여 원형 큐처럼 시작과 끝이 연결된 배열을 모델로 했습니다. 로봇이 있는 n 크기의 배열까지 총 2개의 배열을 이용하여 풀었습니다.

 

1. 벨트가 한 칸 회전한다.

=> left와 right를 1씩 감소시켜줍니다. 벨트는 시계 방향으로 회전합니다. 또, 벨트가 회전했을 시 로봇의 위치도 우측으로 이동하게 되므로 모든 로봇들을 내구도 감소 없이 우측으로 1칸씩 이동시켜줍니다.

2. 로봇이 한 칸 이동한다.

=> 로봇배열과 벨트 배열의 조건을 잘 비교합니다. 로봇 배열에서 이동할 위치는 비어있어야 하며, 벨트 배열에서 이동할 위치의 내구도가 1 이상인지 확인합니다.

3. 로봇을 올린다.

=> left 인덱스의 로봇, 벨트 배열을 확인 후 로봇을 올립니다.

 

모든 과정 중 내구도가 0인 칸이 생긴다면 k의 값을 1씩 감소시켰습니다. 물론 새로운 변수를 만들어 이 값을 증가시키고 k와 비교해도 무방합니다.


전역 변수

int n, k = 문제에서 주어진 입력(크기, 빈 칸 개수)

int map[] = 벨트의 내구도

int left, right = 벨트 배열에서 인덱스를 가리키는 변수
boolean robot[] = 로봇이 존재하는지 저장하는 배열

 

메소드

void main

입력을 받고 k가 0 이하로 될 때까지 while문을 반복합니다. 한 바퀴는 count의 증가, 벨트의 회전, 로봇의 이동, 새 로봇 추가의 동작이 있습니다.

(moveBelt, moveRobot, newRobot 호출)

 

void moveBelt

left, right의 값을 1씩 감소시킵니다. 원형 구조이므로 -1의 값이 된다면 2*n-1(우측)으로 이동시킵니다.

벨트가 회전하면 로봇도 이동해야 하므로 우측으로 1칸씩 당겨줍니다. 내구도 소모는 없습니다.

 

void moveRobot

로봇이 우측으로 이동할 수 있다면 이동합니다. 단, 우측에 내구도가 있으며 로봇이 있으면 안 됩니다. 로봇이 이동했다면 내구도를 1 감소시키고 0이 됐다면 k의 값을 1 감소시킵니다.

 

void newRobot

벨트의 시작 부분(left)에 새 로봇을 놓습니다. 로봇이 놓였다면 내구도를 1 감소시킵니다.

 

 

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class p20055 {
static int n, k, map[], left, right;
static boolean robot[];
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer stz = new StringTokenizer(br.readLine());
n = Integer.parseInt(stz.nextToken());
k = Integer.parseInt(stz.nextToken());
map = new int[2*n];
robot = new boolean[n];
stz = new StringTokenizer(br.readLine());
for(int i = 0; i < 2* n; i++)
map[i] = Integer.parseInt(stz.nextToken());
left = 0;
right = n;
int count = 0;
while(k > 0) {
count++;
moveBelt();
moveRobot();
newRobot();
}
System.out.println(count);
}
public static void moveBelt() {
left--;
right--;
if(left == -1)
left = 2*n-1;
if(right == -1)
right = 2*n-1;
for(int i = n-2; i >= 0; i--) {
if(robot[i]) {
robot[i] = false;
if(i+1 < n-1)
robot[i+1] = true;
}
}
}
public static void moveRobot() {
for(int i = n-2; i >= 0; i--) {
if(robot[i]) {
int next = left+i+1;
if(next >= 2*n)
next -= 2*n;
if(!robot[i+1] && map[next] >= 1) {
robot[i] = false;
if(i+1 < n-1)
robot[i + 1] = true;
map[next]--;
if(map[next] == 0)
k--;
}
}
}
}
public static void newRobot() {
if(!robot[0] && map[left] > 0) {
robot[0] = true;
map[left]--;
if(map[left] == 0)
k--;
}
}
}
view raw p20055.java hosted with ❤ by GitHub
반응형
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2025/04   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30
글 보관함