알고리즘/백준
[백준] 20055 - 컨베이어 벨트 위의 로봇
person456
2024. 3. 17. 14:36
난이도 - G5
사용 개념 - 구현, 자료구조(Queue)
핵심 키워드
* 1. 로봇은 n-1위치에 존재할 때 내릴 수 있다면 무조건 내린다.
* 2. 컨베이어 벨트의 작업 순서에 유의해야 한다.
1) 컨베이어 벨트가 먼저 회전한다. 벨트 위에 로봇이 존재한다면 로봇을 포함하여 회전한다.
2) 이후 로봇이 움직일 수 있다면 "먼저 들어온 로봇의 순서대로" 앞으로 1칸 이동한다.
3) 이후 0번 인덱스에 존재하는 컨베이어 벨트의 내구도가 1보다 크고 로봇이 없다면, 로봇을 올리고 내구도를 1 감 소한다.
4) 이 과정 속에서 로봇이 n-1에 존재한다면, 무조건 내린다.
* 3. 내구도가 0인 칸의 개수가 K개 이상이라면 과정을 종료한다. 그렇지 않다면 1번으로 돌아간다.
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
|
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.*;
public class Main {
static StringTokenizer st;
static StringBuilder sb;
static int n,m,k;
static int[] conveyor;
static Queue<Integer> q;
public static void main(String[] args)throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
st = new StringTokenizer(br.readLine(), " ");
n = Integer.parseInt(st.nextToken());
m = Integer.parseInt(st.nextToken());
q = new ArrayDeque<>();
conveyor = new int[n*2];
int loop = 1;
st = new StringTokenizer(br.readLine(), " ");
for(int i=0; i<conveyor.length; i++){
conveyor[i] = Integer.parseInt(st.nextToken());
}
int[] isRobot = new int[n*2];
while(true){
moveConveyor(isRobot); // 1. 컨베이어 이동
moveRobot(isRobot); // 2. 로봇 이동
if(conveyor[0] > 0){ // 3. 0번 위치가 비어있다면 올리기.
if(isRobot[0] != 1){
isRobot[0] = 1;
conveyor[0] --;
q.offer(0);
}
}
int cnt = isEmpty(); // 4. 빈 컨베이어 체크
if(cnt>=m)break;
loop++;
}
sb = new StringBuilder();
sb.append(loop);
System.out.println(sb.toString());
}
static void moveRobot(int[] isRobot){
int size = q.size();
for(int i=0; i<size; i++){
int index = q.poll();
int now = (index+1)>=(n*2-1)?(index+1)%(n*2) : index+1;
int next = (index+2)>=(n*2-1)?(index+2)%(n*2) : index+2;
if(conveyor[next]>0){
if(isRobot[next]==1){
q.offer(now);
continue;
}
conveyor[next]--;
isRobot[now] = 0;
if(next == n-1){
}
else{
isRobot[next] = 1;
q.offer(next);
}
}
else{
q.offer(now);
}
}
}
static int isEmpty(){
int cnt =0 ;
for(int i=0; i<conveyor.length; i++){
if(conveyor[i]<=0){
cnt++;
}
}
return cnt;
}
static void moveConveyor(int[] isRobot){
int last = conveyor[conveyor.length-1];
boolean flag = false;
if(isRobot[conveyor.length-1] == 1){
flag = true;
isRobot[conveyor.length-1]=0;
}
for(int i = conveyor.length-2; i>=0; i--){
if(isRobot[i] == 1){
if(i+1 == n-1){
isRobot[i]=0;
q.remove(i);
}
else{
isRobot[i+1] = 1;
isRobot[i] = 0;
}
}
conveyor[i+1] = conveyor[i];
}
conveyor[0] = last;
if(flag){
isRobot[0] = 1;
}
}
}
|
cs |
어려웠던 점
- 로봇이 "먼저 들어온 순서"대로 처리하는 점이 생각보다 어려웠다. Queue의 선입선출 개념을 활용하여 로봇이 존재했던 Index를 Queue에 저장하여 해결하고자 하였는데, 로봇이 0번 인덱스에 저장되어도 "벨트 이동" + "로봇 이동"의 결과가 정상적으로 처리되면 해당 Index를 가공처리 해줘야 했다.