문제 링크 : https://www.acmicpc.net/problem/14499
14499번: 주사위 굴리기
첫째 줄에 지도의 세로 크기 N, 가로 크기 M (1 ≤ N, M ≤ 20), 주사위를 놓은 곳의 좌표 x, y(0 ≤ x ≤ N-1, 0 ≤ y ≤ M-1), 그리고 명령의 개수 K (1 ≤ K ≤ 1,000)가 주어진다. 둘째 줄부터 N개의 줄에 지
www.acmicpc.net
문제 이해 :
- 지도 위에서, 주사위를 공처럼 굴리는 것을 상상
- 한 칸 굴렸을 때, 밑면의 숫자는 변하고, 윗면은 출력
- 주사위가 굴러갈 때, 어떻게 변하는 지 확인!!
접근 과정 :
- 굴러가는 방향에 따라, 주사위의 변화를 확인했고 이를 어떻게 반영할지 고민!!
- 첫번째 아이디어
- 주사위를 한 칸 굴리면 방향에 따라 한 칸씩 이동하니 이를 리스트로 담아서 저장하자!!
- 주사위의 가로와 세로를 저장할 리스트를 생성하고, 이를 한 칸씩 이동시켜서 굴리기를 반영
- 두번째 아이디어
- 주사위 배열을 두고, 방향에 따라 변하는 4개의 면을 즉시 반영
소스 코드 및 결과 :
/*
주사위 굴리기
** 주사위의 가로와 세로를 따로 기억하면서 굴리기!
*/
import java.io.*;
import java.util.*;
public class BOJ14499_copy {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int N = Integer.parseInt(st.nextToken());
int M = Integer.parseInt(st.nextToken());
int x = Integer.parseInt(st.nextToken());
int y = Integer.parseInt(st.nextToken());
int K = Integer.parseInt(st.nextToken());
int[][] map = new int[N][M];
for (int i = 0; i < N; i++) {
st = new StringTokenizer(br.readLine());
for (int j = 0; j < M; j++) {
map[i][j] = Integer.parseInt(st.nextToken());
}
}
List<Integer> horizontalDice = new ArrayList<>();
List<Integer> verticalDice = new ArrayList<>();
int[] dice = new int[7];
horizontalDice.add(4);
horizontalDice.add(1);
horizontalDice.add(3);
horizontalDice.add(6);
verticalDice.add(1);
verticalDice.add(5);
verticalDice.add(6);
verticalDice.add(2);
StringBuilder sb = new StringBuilder();
st = new StringTokenizer(br.readLine());
while (K-- > 0) {
int k = Integer.parseInt(st.nextToken());
int nx = x + dx[k];
int ny = y + dy[k];
if (nx < 0 || nx >= N || ny < 0 || ny >= M) {
continue;
}
switch (k) {
case 1:
y++;
verticalDice.set(0, horizontalDice.get(2));
verticalDice.set(2, horizontalDice.get(0));
horizontalDice.add(horizontalDice.get(0));
horizontalDice.remove(0);
break;
case 2:
y--;
verticalDice.set(0, horizontalDice.get(0));
verticalDice.set(2, horizontalDice.get(2));
horizontalDice.add(0, horizontalDice.get(3));
horizontalDice.remove(4);
break;
case 3:
x--;
horizontalDice.set(1, verticalDice.get(3));
horizontalDice.set(3, verticalDice.get(1));
verticalDice.add(0, verticalDice.get(3));
verticalDice.remove(4);
break;
case 4:
x++;
horizontalDice.set(1, verticalDice.get(1));
horizontalDice.set(3, verticalDice.get(3));
verticalDice.add(verticalDice.get(0));
verticalDice.remove(0);
break;
}
if (map[x][y] == 0) {
map[x][y] = dice[verticalDice.get(0)];
} else {
dice[verticalDice.get(0)] = map[x][y];
map[x][y] = 0;
}
sb.append(dice[horizontalDice.get(3)] + "\n");
}
System.out.println(sb.toString().trim());
}
static int[] dx = { 0, 0, 0, -1, 1 };
static int[] dy = { 0, 1, -1, 0, 0 };
}
package BOJ;
/*
주사위 굴리기
** 주사위 배열에 이동을 즉시 반영하면서 굴리기
*/
import java.io.*;
import java.util.*;
public class BOJ14499 {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int N = Integer.parseInt(st.nextToken());
int M = Integer.parseInt(st.nextToken());
int x = Integer.parseInt(st.nextToken());
int y = Integer.parseInt(st.nextToken());
int K = Integer.parseInt(st.nextToken());
int[][] map = new int[N][M];
for (int i = 0; i < N; i++) {
st = new StringTokenizer(br.readLine());
for (int j = 0; j < M; j++) {
map[i][j] = Integer.parseInt(st.nextToken());
}
}
int[] dice = new int[7];
StringBuilder sb = new StringBuilder();
st = new StringTokenizer(br.readLine());
while (K-- > 0) {
int k = Integer.parseInt(st.nextToken());
int nx = x + dx[k];
int ny = y + dy[k];
if (nx < 0 || nx >= N || ny < 0 || ny >= M) {
continue;
}
int temp;
switch (k) {
case 1:
y++;
temp = dice[4];
dice[4] = dice[1];
dice[1] = dice[3];
dice[3] = dice[6];
dice[6] = temp;
break;
case 2:
y--;
temp = dice[3];
dice[3] = dice[1];
dice[1] = dice[4];
dice[4] = dice[6];
dice[6] = temp;
break;
case 3:
x--;
temp = dice[1];
dice[1] = dice[2];
dice[2] = dice[6];
dice[6] = dice[5];
dice[5] = temp;
break;
case 4:
x++;
temp = dice[1];
dice[1] = dice[5];
dice[5] = dice[6];
dice[6] = dice[2];
dice[2] = temp;
break;
}
if (map[x][y] == 0) {
map[x][y] = dice[1];
} else {
dice[1] = map[x][y];
map[x][y] = 0;
}
sb.append(dice[6] + "\n");
}
System.out.println(sb.toString().trim());
}
static int[] dx = { 0, 0, 0, -1, 1 };
static int[] dy = { 0, 1, -1, 0, 0 };
}
P.S
주사위를 굴릴 때, 한 칸씩 땡겨지거나 미뤄지는 것을 고려해서 리스트를 활용하려고 했다.
그러나 상하로 굴리던, 좌우로 굴리던 두 방향 모두 반영해야하더라..ㅜㅜ
다 해놓고 보니, 그냥 주사위 배열에 즉시 반영하면서 굴려도 될 것 같았다.
사실, 주사위의 변화 파악만 하면 구현은 크게 차이가 없을 것 같다.
'Algorithm' 카테고리의 다른 글
[백준 Silver 3] 15270 친구 팰린드롬 - Java (0) | 2021.12.16 |
---|---|
[백준 Gold 4] 21923 곡예 비행 - Java (0) | 2021.12.16 |
[백준 Silver 2] 11722 가장 긴 감소하는 부분 수열 - Java (0) | 2021.12.16 |
[백준 Silver 1] 2583 영역구하기 - Java (0) | 2021.12.16 |
[백준 Gold 5] 1987 알파벳 - Java (0) | 2021.04.14 |