-
백준 14499 (주사위 굴리기)백준 문제 2024. 1. 7. 16:39728x90
N * M의 크기의 지도가 있다. 각 지도 칸은 정수가 쓰여있고, 주사위를 동서남북으로 굴려서 주사위의 윗면의 숫자를 출력하는 문제이다.
주사위는 예를 들어 위와 같이 전개도를 가진다. (주사위의 윗면이 1, 밑면이 6이다.)
주사위는 맨처음에 N * M 지도의 [x][y]의 위치에 존재해 있다.
주사위를 굴렸을 때, 이동한 칸에 쓰여 있는 수가 0이면, 주사위의 바닥면에 쓰여 있는 수가 칸에 복사된다.
0이 아닌 경우에는 칸에 쓰여 있는 수가 주사위의 바닥면으로 복사되며, 칸에 쓰여 있는 수는 0이 된다.
만약 이동할 수 없는 칸이면 무시해도 좋다.
맨처음 주사위의 쓰여진 숫자는 6면 모두 0으로 시작한다.
문제의 조건대로 차근차근 설계를 해보자
1번 : 먼저 주사위가 이동할 수 있는 칸인지 확인 한다. 만약 이동할 수 없으면 1번을 계속 반복한다.
2번 : 주사위를 이동시킨다.
3번 : 이동시킨 칸의 숫자를 확인해 조건을 처리한다.(0이면 주사위 바닥면 복사, 그렇지 않으면...)
4번 : 현재 주사위의 윗면을 출력한다.
1) 주사위 이동 여부 확인
for(int i = 0;i<k;i++){ int dir = Integer.parseInt(st.nextToken()); if(dir == 1){ //동 if(y + 1>=m)continue; y++; } else if(dir == 2){ //서 if(y-1 < 0 )continue; y--; } else if(dir == 3){ //북 if(x - 1 < 0)continue; } else{ //남 if(x + 1 >= n)continue; x ++; } }
2) 주사위 이동
이번 문제에서 가장 관건이 되는 부분이다.
먼저 주사위에 씌여진 숫자를 기억해야 하므로 dice라는 1차원 배열을 만든다.
그 다음 현재 주사위에서 동서남북으로 이동했을 때 주사위 면의 숫자가 어떻게 바뀌는지 규칙을 찾아낸다.
그림에서 보면 노란색으로 칠한부분은 수정되는 부분이다.
dice[0] = 윗면, dice[5] = 밑면 이다.
예를 들어 처음 배열을 1 2 3 4 5 6이라고 한다고 가정하자
동으로 움직이면 4 2 1 6 5 3이 된다.
서로 움직이면 3 2 6 1 5 4가 된다.
남으로 움직이면 2 6 3 4 1 5가 된다.
북으로 움직이면 5 1 3 4 6 2가 된다.
for(int i = 0;i<k;i++){ int dir = Integer.parseInt(st.nextToken()); if(dir == 1){ //동 if(y + 1>=m)continue; y++; int temp = 0; temp = dice[0]; dice[0] = dice[3]; dice[3] = dice[5]; dice[5] = dice[2]; dice[2] = temp; } else if(dir == 2){ //서 if(y-1 < 0 )continue; y--; int temp = 0; temp = dice[0]; dice[0] = dice[2]; dice[2] = dice[5]; dice[5] = dice[3]; dice[3] = temp; } else if(dir == 3){ //북 if(x - 1 < 0)continue; x--; int temp = 0; temp = dice[0]; dice[0] = dice[4]; dice[4] = dice[5]; dice[5] = dice[1]; dice[1] = temp; } else{ //남 if(x + 1 >= n)continue; x ++; int temp =0; temp = dice[0]; dice[0] = dice[1]; dice[1] = dice[5]; dice[5] = dice[4]; dice[4] = temp; } }
3) 지도와 이동 된 주사위의 조건 적용
public static void movingAndCopy(){ if(arr[x][y] == 0){ arr[x][y] = dice[5]; } else{ dice[5] = arr[x][y]; arr[x][y] = 0; } }
4) 말 그대로 dice[0]을 출력해주면 된다.
전체 코드이다.
public class 연습용 { private static int []dice; private static int [][]arr; private static int x; private static int y; 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()); x = Integer.parseInt(st.nextToken()); y = Integer.parseInt(st.nextToken()); int k = Integer.parseInt(st.nextToken()); arr = new int[n][m]; for(int i=0;i<n;i++){ st = new StringTokenizer(br.readLine()); for(int j = 0;j<m;j++){ arr[i][j] = Integer.parseInt(st.nextToken()); } } dice = new int[6]; // dice[0] = 윗면, dice[5] = 밑면 st = new StringTokenizer(br.readLine()); for(int i = 0;i<k;i++){ int dir = Integer.parseInt(st.nextToken()); if(dir == 1){ //동 if(y + 1>=m)continue; y++; int temp = 0; temp = dice[0]; dice[0] = dice[3]; dice[3] = dice[5]; dice[5] = dice[2]; dice[2] = temp; movingAndCopy(); } else if(dir == 2){ //서 if(y-1 < 0 )continue; y--; int temp = 0; temp = dice[0]; dice[0] = dice[2]; dice[2] = dice[5]; dice[5] = dice[3]; dice[3] = temp; movingAndCopy(); } else if(dir == 3){ //북 if(x - 1 < 0)continue; x--; int temp = 0; temp = dice[0]; dice[0] = dice[4]; dice[4] = dice[5]; dice[5] = dice[1]; dice[1] = temp; movingAndCopy(); } else{ //남 if(x + 1 >= n)continue; x ++; int temp =0; temp = dice[0]; dice[0] = dice[1]; dice[1] = dice[5]; dice[5] = dice[4]; dice[4] = temp; movingAndCopy(); } System.out.println(dice[0]); } } public static void movingAndCopy(){ if(arr[x][y] == 0){ arr[x][y] = dice[5]; } else{ dice[5] = arr[x][y]; arr[x][y] = 0; } } }
'백준 문제' 카테고리의 다른 글
백준 12100 (2048 (Easy)) (0) 2024.01.29 백준 21608 (상어 초등학교) <우선순위 큐 정렬 응용> (0) 2024.01.12 백준 16236 (아기상어) JAVA (1) 2023.10.26 백준 1197(최소 스패닝 트리) JAVA <MST, 크루스칼 알고리즘> (0) 2023.07.21 백준 1325(효율적인 해킹) JAVA (0) 2023.07.19