[백준 / C++] 14499번: 주사위 굴리기 (삼성 SW 역량 테스트 기출)

728x90
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

 

난이도: solved.ac 골드 4

 

구현 방법

board라는 2차원 배열에 지도에 적힌 번호를 저장했다.

그리고 dice라는 배열에 주사위의 각 면에 적힌 번호를 저장했다.

 

dice[0]는 밑면에 적힌 번호, dice[1]는 윗면에 적힌 번호

dice[2]는 왼쪽면에 적힌 번호, dice[3]는 오른쪽면에 적힌 번호

dice[4]는 앞면에 적힌 번호, dice[5]는 뒷면에 적힌 번호를 뜻한다.

 

주사위를 네 가지 방향으로 굴리면 각각 어떻게 되는지 알 수 있다.

 

1. 동쪽으로 굴릴 때

dice[3] → dice[0]

dice[1] → dice[3]

dice[2] → dice[1]

dice[0] → dice[2]

 

2. 서쪽으로 굴릴 때

dice[2] → dice[0]

dice[1] → dice[2]

dice[3] → dice[1]

dice[0] → dice[3]

 

3. 북쪽으로 굴릴 때

dice[5] → dice[0]

dice[1] → dice[5]

dice[4] → dice[1]

dice[0] → dice[4]

 

4. 남쪽으로 굴릴 때

dice[4] → dice[0]

dice[1] → dice[4]

dice[5] → dice[1]

dice[0] → dice[5]

 

그리고 주사위의 위치는 주사위를 굴릴 때마다 각 방향으로 한 칸 이동한다.

주사위의 초기 위치는 (x, y)이다.

 

주사위를 동쪽으로 굴리면 y = y + 1이 되고

서쪽으로 굴리면 y = y - 1이 되고

남쪽으로 굴리면 x = x + 1이 되고

북쪽으로 굴리면 x = x - 1이 된다.

 

주사위를 이동시키기 전에 주사위를 굴렸을 때 이동할 수 있는지 없는지부터 확인해야 한다.

그래서 move라는 함수로 주사위를 굴렸을 때 이동할 위치의 좌표를 찾고

범위 내에 있다면 한 칸 이동하고 1을 리턴하게 했고, 범위를 벗어난다면 0을 리턴하게 했다.

move의 리턴 값이 1이면 주사위가 이동할 수 있다는 걸 뜻하므로 rotate 함수를 호출해 dice의 인덱스로 주사위의 면에 쓰인 번호를 변경시켰다.

 

코드

#include <bits/stdc++.h>
using namespace std;
// 백준 14499번: 주사위 굴리기 (골드 4)
int board[20][20];	// 지도의 각 칸 번호 저장
int dice[6];	// 주사위 각 자리 번호 저장
/*
	dice[0] = 주사위 밑면, dice[1] = 주사위 윗면
	dice[2] = 주사위 왼쪽면, dice[3] = 주사위 오른쪽면
	dice[4] = 주사위 앞면, dice[5] = 주사위 뒷면
*/
int N, M, x, y, K;
int move(int dir);	// 움직일 수 있으면 이동하고 1을 리턴, 이동하지 못하면 곧바로 0을 리턴 (회전 X)
void rotate(int dir);	// 주사위 회전

int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	int i, j, dir;
	cin >> N >> M >> x >> y >> K;
	for (i = 0; i < N; i++)
		for (j = 0; j < M; j++)
			cin >> board[i][j];
	for (i = 0; i < K; i++) {
		cin >> dir;
		// 이동 가능할 때만 명령을 수행하고 출력함
		if (move(dir)) {
			// 주사위 회전
			rotate(dir);
			// 지도의 현재 칸이 0이 아닐 때
			if (board[x][y]) {
				dice[0] = board[x][y];	// 지도의 현재 칸 번호를 주사위 밑면 번호로 복사
				board[x][y] = 0;	// 지도의 현재 칸 0으로 지움
			}
			else
				board[x][y] = dice[0];	// 주사위 밑면 번호를 지도의 현재 칸으로 복사
			cout << dice[1] << "\n";
		}
	}
}

int move(int dir) {
	if (dir == 1 &&  y + 1 < M) {
		y++;
		return 1;
	}
	else if (dir == 2 && y - 1 >= 0) {
		y--;
		return 1;
	}
	else if (dir == 3 && x - 1 >= 0) {
		x--;
		return 1;
	}
	else if (dir == 4 && x + 1 < N) {
		x++;
		return 1;
	}
	return 0;
}

void rotate(int dir) {
	int tmp = dice[0];
	if (dir == 1) {
		dice[0] = dice[3];
		dice[3] = dice[1];
		dice[1] = dice[2];
		dice[2] = tmp;
	}
	else if (dir == 2) {
		dice[0] = dice[2];
		dice[2] = dice[1];
		dice[1] = dice[3];
		dice[3] = tmp;
	}
	else if (dir == 3) {
		dice[0] = dice[5];
		dice[5] = dice[1];
		dice[1] = dice[4];
		dice[4] = tmp;
	}
	else if (dir == 4) {
		dice[0] = dice[4];
		dice[4] = dice[1];
		dice[1] = dice[5];
		dice[5] = tmp;
	}
}

 

성능

백준 14499번 주사위 굴리기 c++ 코드 제출 결과
코드 제출 결과

 

반응형