문제 링크
https://www.acmicpc.net/problem/14499
접근 방법
복잡한 알고리즘성 문제가 아닌 시뮬레이션 문제였습니다.
주사위를 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 |