문제 링크


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가지 방향으로 굴렸을때 각 면의 값이 어떻게 이동하는지 그림을 그려보면서 접근하였고, 매번 이동을 진행하기 전에 좌표에 대한 검사를 진행하였습니다. dice[6] 배열을 선언하여 주사위의 각면에 번호를 매겨서 접근하였지만, 번호로 보니 햇갈려서 각 번호 면에 대하여 참조 변수를 알아보기 쉽게 선언하였습니다.

아래와 같이 각 면을 참조한 뒤, 설명대로 주사위를 움직입니다. 움직일 때 마다 주사위의 면의 값 뿐만 아니라, 좌표 이동도 해줍니다.

int& north = dice[0],

west = dice[1], 

top = dice[2], 

east = dice[3], 

south = dice[4], 

bot = dice[5];

 

이동이 끝난 뒤에는 현재 위치의 지도값이 0인지, 0이 아닌지에 따라 다른 처리를 해주었고, 만약 이동할 수 없는 경우 함수 자체에서 false를 반환하였고, 이동이 성공한 경우 true를 반환하여 지도값에 따른 처리를 해주었습니다.

 

처음에 입력으로 주는 주사위의 초기 위치를 x, y 거꾸로 받아서 한참을 해맸는데, 아마 이 부분 실수하는 분들이 많을 것 같습니다.

 

 

소스 코드


#include <cstring>
#include <iostream>
#define MAX 21
#define MAXK 1001
#define NUMD 5
#define NUM_DICE 6
using namespace std;
typedef struct coord {
	int y, x;
};
int N, M, K, map[MAX][MAX], cmd[MAXK];
coord cur;
int dice[6];
const coord direction[NUMD] = { {0, 0}, {0, 1}, {0, -1}, {-1, 0}, {1, 0} }; // 0, 동, 서, 북, 남
int& north = dice[0], west = dice[1], top = dice[2], east = dice[3], south = dice[4], bot = dice[5];

// 0 = north
// 1 = west
// 2 = top
// 3 = east
// 4 = south
// 5 = bot

bool isRanged(int y, int x) {
	if (y >= N || x >= M || y < 0 || x < 0) return false;
	return true;
}

bool move_dice(int d) {
	int ny, nx;
	int temp;
	ny = cur.y + direction[d].y;
	nx = cur.x + direction[d].x;
	if (!isRanged(ny, nx)) return false;
	if (d == 1) { // 동
		temp = east;
		east = top;
		top = west;
		west = bot;
		bot = temp;
	}
	else if (d == 2) { // 서
		temp = west;
		west = top;
		top = east;
		east = bot;
		bot = temp;
	}
	else if (d == 3) { // 북
		temp = north;
		north = top;
		top = south;
		south = bot;
		bot = temp;
	}
	else { // 남
		temp = bot;
		bot = south;
		south = top;
		top = north;
		north = temp;
	}
	cur.y = ny;
	cur.x = nx;
	return true;
}

void solve() {
	for (int k = 0; k < K; ++k) {
		if (move_dice(cmd[k])) { // 움직였다면
			if (map[cur.y][cur.x] == 0) { // 지도칸이 0이라면
				map[cur.y][cur.x] = bot;
			}
			else { // 지도칸이 0이 아니라면, 칸의 수가 주사위 바닥으로 복사, 칸은 0
				bot = map[cur.y][cur.x];
				map[cur.y][cur.x] = 0;
			}
			cout << top << "\n";
		}
	}
}

int main() {
	ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
	cin >> N >> M >> cur.y >> cur.x >> K;
	memset(dice, 0, sizeof(dice));
	for (int i = 0; i < N; ++i)
		for (int j = 0; j < M; ++j)
			cin >> map[i][j];
	for (int k = 0; k < K; ++k) cin >> cmd[k]; // 1: 동, 2: 서, 3: 북, 4: 남
	solve();
	return 0;
}

개발 환경은 VS 2019입니다.

질문, 지적 환영합니다. 감사합니다!!

'알고리즘 > 백준' 카테고리의 다른 글

[C++] 백준 14501 퇴사  (0) 2020.05.19
[C++] 백준 12865 평범한 배낭  (2) 2020.05.18
[C++] 백준 15686 치킨 배달  (0) 2020.05.18
[C++] 백준 16236 아기 상어  (0) 2020.05.18
[C++] 백준 11066 파일 합치기  (1) 2020.05.17

+ Recent posts