CS/알고리즘_삼성 SW 역량 테스트 기출 문제

삼성 SW 역량 테스트 기출 문제 : 주사위 굴리기

Jedy_Kim 2021. 10. 19. 00:11
728x90

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

// 코드

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
104
105
106
107
108
109
110
import java.util.*;
import java.io.*;
 
class Main{   
  
  static int N, M, R, C, K; // 지도의 세로, 가로, 주사위의 R, C, 명령의 개수
  static int[][] map;
  
  // 방향에 따른 좌표 변화 : 동(1)/서(2)/북(3)/남)4)
  static int[][] deltas = {{}, {01}, {0-1}, {-10}, {10}};
  
  public static void main(String[] args) throws Exception {
    // Please Enter Your Code Here
    BufferedWriter bw  = new BufferedWriter(new OutputStreamWriter(System.out));
    BufferedReader br  = new BufferedReader(new InputStreamReader(System.in));
    StringTokenizer st = new StringTokenizer(br.readLine());
    StringBuilder sb   = new StringBuilder();
    
    N = Integer.parseInt(st.nextToken());
    M = Integer.parseInt(st.nextToken());
    R = Integer.parseInt(st.nextToken());
    C = Integer.parseInt(st.nextToken());
    K = Integer.parseInt(st.nextToken());
    
    map = new int[N][M];
    for(int i=0; i<N; ++i) {
      map[i] = Arrays.stream(br.readLine().split(" ")).mapToInt(Integer::parseInt).toArray();
    } // 지도 입력완료
    
    
    
    st = new StringTokenizer(br.readLine());
    Dice dice = new Dice();
    for(int k=0; k<K; ++k) {
      int dir = Integer.parseInt(st.nextToken());
      // 이 방향으로 굴리면서 정답출력
      int nr = R + deltas[dir][0];
      int nc = C + deltas[dir][1];
      
      if(!isIn(nr, nc)) continue;
      
      R = nr;
      C = nc;
      
      int top = dice.roll(dir, R, C); 
      sb.append(top).append("\n");
    }
    
    bw.write(sb.toString());
    br.close();
    bw.flush();
    bw.close();
  }
  
  private static boolean isIn(int r, int c) {
    return (0<=&& r<&& 0<=&& c<M);
  }
  
  static class Dice {
    
    int[] dice = new int[6];
    // 주사위의 방향을 미리 변수로 만들어 둔다.
    int TOP = 0, BOTTOM = 1, FRONT = 2, REAR = 3, LEFT = 4, RIGHT = 5;
    
    public int roll(int d, int r, int c) {
      // 동쪽으로 돌릴 때
      if(d == 1) {
        // bottom -> left -> top -> right -> bottom
        rotate(BOTTOM, LEFT, TOP, RIGHT);
      }
      // 서쪽으로 돌릴 때
      else if(d == 2) {
        // bottom -> right -> top -> left -> bottom
        rotate(BOTTOM, RIGHT, TOP, LEFT);
      }
      // 북쪽으로 돌릴 때
      else if(d == 3) {
        // bottom -> front -> top -> rear -> bottom
        rotate(BOTTOM, FRONT, TOP, REAR);
      }
      // 남쪽으로 돌릴 때
      else {
        // bottom -> rear -> top -> front -> bottom
        rotate(BOTTOM, REAR, TOP, FRONT);
      }
      
      // 바닥의 값에 따라서 주사위와 상호작용
      if(map[r][c] == 0) { // 주사위의 값을 map에 복사해주기
        map[r][c] = dice[BOTTOM];
      } 
      else { // map의 값을 주사위에 복사하기, 지도는 0
        dice[BOTTOM] = map[r][c];
        map[r][c] = 0;
      }
      
      // 꼭대기의 값을 반환
      return dice[TOP];
    }
    
    private void rotate(int a, int b, int c, int d) {
      int temp = dice[d];
      dice[d] = dice[c];
      dice[c] = dice[b];
      dice[b] = dice[a];
      dice[a] = temp;
    }
    
  }
  
}
cs

 

// 2회독 

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
import java.util.*;
import java.io.*
 
 
public class Main { 
  
  // 동쪽은 1, 서쪽은 2, 북쪽은 3, 남쪽은 4
  static final int[][] DELTAS = { {}, {01}, {0-1}, {-10}, {10} };
  static int N, M, R, C, K;
  static int[][] map;
  
  
  // 주사위의 숫자 변화 상태를 관리하는 클래스
  static class Dice {
    
    // 주사위
    int[] dice = new int[6];
    // 주사위의 방향을 미리 변수값으로 정의해둔다.
    int TOP=0, BOTTOM=1, FRONT=2, REAR=3, LEFT=4, RIGHT=5;
    
    public int roll (int d, int r, int c) {
      // 1-1. 동쪽으로 돌릴 때 => 1칸 회회전시키면 된다
      // bottom -> left -> top -> right -> bottom
      if ( d == 1 ) rotate(BOTTOM, LEFT, TOP, RIGHT);
      // 1-2. 서쪽으로 돌릴 때 => 2칸 회전시키면 된다 (방향을 바꿀필요가 없다.)
      // bottom -> right -> top -> left -> bottom
      else if ( d == 2 ) rotate(BOTTOM, RIGHT, TOP, LEFT);
      // 1-3. 북쪽으로 돌릴 때 => 1칸 회전시키면 된다
      // bottom -> front -> top -> rear -> bottom
      else if ( d == 3 ) rotate(BOTTOM, FRONT, TOP, REAR);
      // 1-4. 남쪽으로 돌릴 때 * 2 => 2칸 회전시키면 된다 
      // bottom -> rear -> top -> front -> bottom
      else rotate(BOTTOM, REAR, TOP, FRONT);
      
      // 2. 바닥의 값에 따라 처리를 해준다.
      // 2-1. 바닥이 0인 경우 : 주사위의 바닥면에 쓰여 있는 수가 칸에 복사된다.
      if ( map[r][c] == 0 ) map[r][c] = dice[BOTTOM];
      // 2-2. 0이 아닌 경우 : 칸에 쓰여 있는 수가 주사위의 바닥면으로 복사되며, 칸에 쓰여 있는 수는 0이 된다.
      else { dice[BOTTOM] = map[r][c]; map[r][c] = 0; }
      
      // 주사위 상단 부분 값을 반환한다.
      return dice[TOP];
    }
    
    // dice를 회전시킨다
    private void rotate(int a, int b, int c, int d) {
      int temp = dice[d];
      dice[d]  = dice[c];
      dice[c]  = dice[b];
      dice[b]  = dice[a];
      dice[a]  = temp;
    }
    
  }
  
  
  // main
  public static void main(String[] args) throws Exception{
    
    // Please Enter Your Code Here
    BufferedWriter bw  = new BufferedWriter(new OutputStreamWriter(System.out));
    BufferedReader br  = new BufferedReader(new InputStreamReader(System.in)); 
    StringTokenizer st = new StringTokenizer(br.readLine());
    StringBuilder   sb = new StringBuilder();
    
    N = Integer.parseInt(st.nextToken());
    M = Integer.parseInt(st.nextToken());
    R = Integer.parseInt(st.nextToken());
    C = Integer.parseInt(st.nextToken());
    K = Integer.parseInt(st.nextToken());
    
    // map을 셋팅한다.
    map = new int[N][];
    for(int i=0; i<N; ++i) map[i] = Arrays.stream(br.readLine().split(" ")).mapToInt(Integer::parseInt).toArray();
    
    // 주사위를 돌린다.
    Dice dice = new Dice();
    st = new StringTokenizer(br.readLine());
    
    for(int i=0; i<K; ++i) {
      int dir = Integer.parseInt(st.nextToken());
      
      // 주어진 방향의 좌표값
      int ny = R + DELTAS[dir][0], nx = C + DELTAS[dir][1];
      // 범위를 벗어날 경우 필터링
      if( ny < 0 || ny >= N || nx < 0 || nx >= M) continue;
      // 바뀐 위치를 갱신해준다.
      R = ny; C = nx;
      // 해당 방향으로 주사위를 굴려 찾고자하는 top값을 구한다.
      int top = dice.roll(dir, R, C);
      sb.append(top).append("\n");
    }
    
    bw.write(sb.toString());
    bw.flush();
    bw.close();
    br.close();
  } 
cs

 

반응형