[백준(Baekjoon)][자바(java)] [삼성 SW 역량 테스트 기출 문제] 14499 : 주사위 굴리기

728x90

 

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

 

문제 풀이

 

import java.io.*;
import java.util.*;

public class Main {
	
	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()), m = Integer.parseInt(st.nextToken());
		int x = Integer.parseInt(st.nextToken()), y = Integer.parseInt(st.nextToken());
		int k = Integer.parseInt(st.nextToken());
		int a[][] = new int[n][m], i, j;  // map array
		for (i = 0; i < n; ++i) {
			st = new StringTokenizer(br.readLine());
			for (j = 0; j < m; ++j) 
				a[i][j] = Integer.parseInt(st.nextToken());
		}
		st = new StringTokenizer(br.readLine());
		br.close();
		
		int[] dx = { 0, 0, 0, -1, 1 }, dy = { 0, 1, -1, 0, 0 };  // directional x/y
		int nx, ny, c, t, b, nt, nb;  // next x/y, command, top/bottom index (+next)
		final int s = 7;
		int[] v = new int[s], d = { 1, 4, 3, 5, 2 };  // dice value/index array ( (M), E, W, N, S )
		StringBuilder sb = new StringBuilder();
		for (i = 0; i < k; ++i) {
			c = Integer.parseInt(st.nextToken());
			nx = x + dx[c];
			ny = y + dy[c];
			if (nx < 0 || nx >= n || ny < 0 || ny >= m)
				continue;
			x = nx;
			y = ny;
			t = d[0];
			b = s - t;
			nt = d[c];
			nb = s - nt;
			d[0] = nt;
			d[c] = b;
			d[c % 2 == 1 ? c + 1 : c - 1] = t;
			if( a[x][y] == 0 )
				a[x][y] = v[nb];  // 주사위 바닥면 숫자가 칸에 복사
			else {
				v[nb] = a[x][y];  // 칸 숫자가 주사위 바닥면에 복사
				a[x][y] = 0;
			}
			sb.append( v[nt] + "\n" );
		}
		
		System.out.println( sb.toString() );
	}
}

 

*  변수
-  c ( command )  :  주사위 이동 명령  ( 동쪽은 1, 서쪽은 2, 북쪽은 3, 남쪽은 4 )
-  x  :  현재 주사위의 x 좌표
-  y  :  현재 주사위의 y 좌표
-  nx ( next x )  :  이동 후 〃
-  ny ( next y )  :  이동 후 〃
-  t ( top )  :  현재 주사위의 상단 숫자
-  b ( bottom )  :  현재 주사위의 하단(바닥면) 숫자
-  nt ( next top )  :  이동 후 〃
-  nb ( next bottom )  :  이동 후 〃
-  dx[], dy[] ( direction )  :  방향 배열  ( -, 동, 서, 북, 남 순서 )
-  v[] ( dice value array )  :  주사위 면의 값 배열
-  d[] ( dice index by direction array )  :  특정 방향으로 주사위 이동 시 상단 면의 인덱스 배열

 

*  문제에 제시된 주사위 전개도
 ( 상단 파란색, 하단 초록색, 양옆 빨간색, 위아래 노란색으로 표시함 )

 

*  v[]
-  i  :  주사위의 6면에 대한 인덱스  ( 1 <= i <= 6 )
-  v[i]  :  각 주사위 면의 값  ( v : dice value array )
-  초기 상태

 

*  d[]
-  i   :  주사위의 이동 방향( c )  ( 1 <= i <= 4 )  ( 동쪽은 1, 서쪽은 2, 북쪽은 3, 남쪽은 4 )
-  d[i]  :  주사위 상단 인덱스( t )가 d[0]일 때, i 방향으로 주사위 이동 후 상단 인덱스( nt )
             ( 주사위 하단(바닥면) 인덱스
( b ) = 7 - t )
-  초기 상태

-  모든 경우

 

*  주사위 이동 시 ( c 방향으로 )  ( 현재  t = d[0],  nt = d[c],  b = 7 - t  )
지도 범위( 0 <= r < n, 0 <= c < m )를 벗어나면 명령 수행 안 함
-  상단 인덱스는 nt가 됨  ( d[0] = nt )
이동한 방향의 반대쪽 인덱스는 b가 됨  ( d[c] = b( ex) 동쪽으로 이동 시 왼쪽 인덱스 )

-  방향( c )이 동쪽( 1 ) 또는 북쪽( 3 )일 경우 d[c+1] = t;
                   서쪽( 2 ) 또는 남쪽( 4 )일 경우 d[c-1] = t;
-  이동한 칸에 쓰여 있는 숫자( a[x][y] )가 0인 경우 주사위 하단(바닥면) 숫자( v[nb] )를 칸에 복사  ( a[x][y] = v[nb]; )
                                                          0이 아닌 경우 칸 숫자를 주사위 바닥면에 복사, 칸 숫자는 0이 됨  ( v[nb] = a[x][y];
a[x][y] = 0; )

 

 

반응형