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
접근 방법
정육면체인 주사위를 굴리는 과정을 어떻게 구현할지가 관건인 문제.
주사위를 X,Y로 굴리면서 밑 면의 숫자가 바뀌도록 하여야 한다.
문제에 나온 주사위 면의 인덱스가 햇갈려서 멋대로 정하여 해결했다.
2
4 1 3
5
6
0
1 2 3
4
5
처음에는 각 면에서 4방향으로 움직일 경우 어떻게 되는지 생각해보았다.
예를 들어, 0인 면이 바닥일 때 왼쪽은 뭐, 오른쪽은 뭐 이런식으로 말이다.
이는 큰 오류가 존재한다.
주사위의 면들은 전체적으로 움직이므로, 내가 생각한 것은 밑면과 4방향의 면만 고려하여 나머지 1면이 업데이트 되지 못한다.
그래서 컨테이너 벨트 처럼 각 면에 적힌 수들이 어떻게 움직일지 생각해보았다.
0
1 2 3
4
5
위 주사위 단면도에서 밑면은 5가 되고, 윗면은 2가 된다.
1)
처음 상태에서 오른쪽(동쪽)으로 움직이면 다음과 같이 바뀐다.
0
5 1 2
4
3
입체적으로 생각해보면, 횡으로 움직이는 면들은 1,2,3,5(처음 단면도에서)이다.
이를 오른쪽으로 하나씩 밀게되면 다음과 같이 바뀐다.
2)
마찬가지로 처음 상태에서 왼쪽으로 움직이면
0
2 3 5
4
1
마찬가지로 왼쪽으로 밀면되므로 다음과 같이 나타난다.
3)
위, 아래는 단면도 그대로 바라보아도 헷갈리지 않으므로 쉽게 생각할 수 있다.
// 위쪽으로
2
1 4 3
5
0
// 아래쪽으로
5
1 0 3
2
4
나머지는 쉽게 구현할 수 있므로 한 번 구현해보자.
코드
#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
#include<cmath>
#include<cstring>
#define MAX 100002
#define INF 100002
using namespace std;
int n, m;
int x, y;
int k;
int map[21][21];
int dice[7];
int curX, curY;
void moveDice(int dir) {
// 오른쪽
if (dir == 1) {
if (curY + 1 >= m) return;
int d3 = dice[3];
int d5 = dice[5];
for (int i = 3; i > 1; i--) {
dice[i] = dice[i - 1];
}
dice[1] = d5;
dice[5] = d3;
curY++;
}
// 왼쪽
else if (dir == 2) {
if (curY - 1 < 0) return;
int d1 = dice[1];
int d5 = dice[5];
for (int i = 1; i < 3; i++) {
dice[i] = dice[i + 1];
}
dice[3] = d5;
dice[5] = d1;
curY--;
}
// 위쪽
else if (dir == 3) {
if (curX - 1 < 0) return;
int d0 = dice[0];
dice[0] = dice[2];
dice[2] = dice[4];
dice[4] = dice[5];
dice[5] = d0;
curX--;
}
// 아래쪽
else if (dir == 4) {
if (curX + 1 >= n) return;
//0 2 4 5
int d5 = dice[5];
dice[5] = dice[4];
dice[4] = dice[2];
dice[2] = dice[0];
dice[0] = d5;
curX++;
}
// 5가 밑면
if (map[curX][curY] != 0) {
dice[5] = map[curX][curY];
map[curX][curY] = 0;
}
else {
map[curX][curY] = dice[5];
}
cout << dice[2] << "\n";
}
int main() {
cin.tie(NULL); ios_base::sync_with_stdio(false);
cin >> n >> m >> x >> y >> k;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
cin >> map[i][j];
}
}
curX = x;
curY = y;
for (int i = 0; i < k; i++) {
int tmp;
cin >> tmp;
moveDice(tmp);
}
}
'📊알고리즘 > BOJ' 카테고리의 다른 글
BOJ 16401 - 과자 나눠주기 (1) | 2024.04.13 |
---|---|
BOJ 2252 - 줄 세우기 (0) | 2024.04.06 |
BOJ 13335 - 트럭 (0) | 2024.03.31 |
BOJ 14891 - 톱니바퀴 (0) | 2024.03.31 |
[시뮬레이션] BOJ 15686 - 치킨 배달 with c++ (0) | 2024.03.24 |