
20055번: 컨베이어 벨트 위의 로봇
길이가 N인 컨베이어 벨트가 있고, 길이가 2N인 벨트가 이 컨베이어 벨트를 위아래로 감싸며 돌고 있다. 벨트는 길이 1 간격으로 2N개의 칸으로 나뉘어져 있으며, 각 칸에는 아래 그림과 같이 1부
www.acmicpc.net
int[] A = new int[2*N+1] : 칸 별로 내구도를 의미
int[][] num = new int[2][N+1] : 각 위치에 무슨 번호의 칸이 있는지를 의미
컨테이너 벨트의 가장 왼쪽 위가 [0][1], 가장 오른쪽 위가 [0][N], 가장 왼쪽 아래가 [1][1], 가장 오른쪽 아래가 [1][N] 위치를 의미한다.
처음에는 num[0][1] = 1번 칸, num[0][2] = 2번 칸, ... num[0][N]= N번 칸 ... num[1][1] = 2*N번 칸이 된다.

boolean[][] robot = new boolean[2][N+1] : 해당 위치에 로봇이 존재하면 true, 존재하지 않으면 false
1. moveBelt() : 벨트가 한 칸 회전한다.
public static void moveBelt() {
int tmp = num[1][1];
for (int i = 1; i < N; i++) {
num[1][i] = num[1][i + 1];
}
num[1][N] = num[0][N];
for (int i = N; i >= 2; i--) {
num[0][i] = num[0][i - 1];
robot[0][i] = robot[0][i - 1];
}
num[0][1] = tmp;
robot[0][1] = false;
robot[0][N] = false;
}
2. moveRobot() : 로봇이 한 칸씩 이동한다. 단, 이동할 위치의 내구도가 0보다 크고, 로봇이 없어야 한다.
로봇이 "내려가는 곳"인 [0][N] 위치는 로봇이 이동하자마자 내려가야 하므로, 마지막에 항상
robot[0][N] = false로 바꿔준다. (로봇이 머물러 있을 수 없음)
public static void moveRobot() {
for (int i = N - 1; i >= 1; i--) {
if (robot[0][i] && !robot[0][i + 1] && A[num[0][i + 1]] > 0) {
robot[0][i] = false;
robot[0][i + 1] = true;
A[num[0][i + 1]]--; // 내구도 감소
}
}
robot[0][N] = false;
}
3. loadRobot() : "올라가는 곳" [0][1] 위치에 새로운 로봇을 올린다. 단, 내구성이 0보다 커야 한다.
마찬가지로, 로봇이 "내려가는 곳"인 [0][N] 위치는 로봇이 이동하자마자 내려가야 하므로, 마지막에 항상
robot[0][N] = false로 바꿔준다. (로봇이 머물러 있을 수 없음)
public static void moveRobot() {
for (int i = N - 1; i >= 1; i--) {
if (robot[0][i] && !robot[0][i + 1] && A[num[0][i + 1]] > 0) {
robot[0][i] = false;
robot[0][i + 1] = true;
A[num[0][i + 1]]--; // 내구도 감소
}
}
robot[0][N] = false;
}
전체 코드 :
import java.io.*; | |
public class n20055 { | |
static int N, K; | |
static int[] A; | |
static int[][] num; | |
static boolean[][] robot; | |
public static void main(String[] args) throws Exception { | |
BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); | |
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out)); | |
String[] input = br.readLine().split(" "); | |
N = Integer.parseInt(input[0]); | |
K = Integer.parseInt(input[1]); | |
num = new int[2][N + 1]; | |
robot = new boolean[2][N + 1]; | |
A = new int[2 * N + 1]; | |
input = br.readLine().split(" "); | |
for (int i = 1; i <= 2 * N; i++) { | |
A[i] = Integer.parseInt(input[i - 1]); | |
} | |
int n = 1; | |
for (int i = 1; i <= N; i++) | |
num[0][i] = n++; | |
for (int i = N; i >= 1; i--) | |
num[1][i] = n++; | |
bw.write(solve() + "\n"); | |
bw.flush(); | |
} | |
public static int solve() { | |
int check = 0; | |
while (checkDurability()) { | |
moveBelt(); | |
moveRobot(); | |
loadRobot(); | |
check++; | |
} | |
return check; | |
} | |
public static boolean checkDurability() { | |
int cnt = 0; | |
for (int i = 1; i <= 2 * N; i++) { | |
if (A[i] == 0) | |
cnt++; | |
} | |
return cnt < K; | |
} | |
public static void loadRobot() { | |
if (A[num[0][1]] > 0) { // 내구도가 0보다 크면 로봇이 올라감 | |
robot[0][1] = true; | |
A[num[0][1]]--; | |
} | |
} | |
public static void moveRobot() { | |
for (int i = N - 1; i >= 1; i--) { | |
if (robot[0][i] && !robot[0][i + 1] && A[num[0][i + 1]] > 0) { | |
robot[0][i] = false; | |
robot[0][i + 1] = true; | |
A[num[0][i + 1]]--; // 내구도 감소 | |
} | |
} | |
robot[0][N] = false; | |
} | |
public static void moveBelt() { | |
int tmp = num[1][1]; | |
for (int i = 1; i < N; i++) { | |
num[1][i] = num[1][i + 1]; | |
} | |
num[1][N] = num[0][N]; | |
for (int i = N; i >= 2; i--) { | |
num[0][i] = num[0][i - 1]; | |
robot[0][i] = robot[0][i - 1]; | |
} | |
num[0][1] = tmp; | |
robot[0][1] = false; | |
robot[0][N] = false; | |
} | |
} |
'BOJ > 삼성 SW 역량테스트' 카테고리의 다른 글
[백준 20057번] 마법사 상어와 토네이도 (java) (0) | 2021.04.23 |
---|---|
[백준 19237번] 어른 상어 (java) (0) | 2021.04.20 |
[백준 20061번] 모노미노도미노 2 (java) (0) | 2021.04.17 |
[백준 17822번] 원판 돌리기 (java) (0) | 2021.04.15 |
[백준 17837번] 새로운 게임 2 (java) (0) | 2021.04.14 |