14499 주사위 굴리기
https://www.acmicpc.net/problem/14499
solution
주사위를 굴리는 방향에 따라 달라질 수 있는 맨 위의 숫자를 출력하는 시뮬레이션/구현 문제이다.
이때 주사위 전개도에 따라서 다음과 같이 크게 2개의 배열로 구분 가능하다.
1. 세로 배열
2. 가로 배열
주사위를 굴리는 방향에 따라서 특정 배열만 회전해주면 된다.
입력이 1, 2 인 경우: 동쪽과 서쪽으로 움직이는 것이기 때문에 가로 배열 회전
입력이 3, 4인 경우: 북쪽과 남쪽으로 움직이는 것이기 때문에 세로 배열 회전
이때 중요한 점은 가로 배열과 세로 배열은 값이 공통인 부분이 존재한다는 것이다. (위쪽과 아래쪽)
따라서 이 부분은 특정 배열을 회전할 때마다 다른 하나의 배열에 값을 복사해준다.
전체 코드
#include <iostream>
#include <vector>
using namespace std;
int N, M, X, Y, K;
int map[20][20];
int dx[4] = {0, 0, -1, 1}; // 주사위 x 방향
int dy[4] = {1, -1, 0, 0}; // 주사위 y 방향
int diceRow[4] = {0, 0, 0, 0}; // 주사위 가로 배열 {뒤, 아래, 앞, 위}
int diceCol[4] = {0, 0, 0, 0}; // 주사위 세로 배열 {왼쪽, 아래, 오른쪽, 위}
// 가로 배열 회전 시 공통 부분 복사
void makeColCopy(int tempX, int tempY) {
// 아래와 오른쪽의 값은 공통임
diceRow[3] = diceCol[3];
diceRow[1] = diceCol[1];
if (map[tempX][tempY] == 0) {
map[tempX][tempY] = diceRow[1];
}
else {
diceRow[1] = diceCol[1] = map[tempX][tempY];
map[tempX][tempY] = 0;
}
}
// 세로 배열 회전 시 공통 부분 복사
void makeRowCopy(int tempX, int tempY) {
// 아래와 오른쪽의 값은 공통임
diceCol[3] = diceRow[3];
diceCol[1] = diceRow[1];
if (map[tempX][tempY] == 0) {
map[tempX][tempY] = diceCol[1];
}
else {
diceRow[1] = diceCol[1] = map[tempX][tempY];
map[tempX][tempY] = 0;
}
}
int main() {
cin>>N>>M>>X>>Y>>K;
for(int i = 0;i < N;i++) {
for(int j = 0;j < M;j++) {
cin>>map[i][j];
}
}
while(K--) {
int dir;
cin>>dir;
// 주사위 굴리는 방향의 좌표
int tempX = X + dx[dir - 1];
int tempY = Y + dy[dir - 1];
// 주사위를 굴리는 방향이 map을 벗어나지 않고 유효한 값인지 체크
if (tempX < 0 || tempY < 0 || tempX >= N || tempY >= M) {
continue;
}
// 동
if (dir == 1) {
int top = diceRow[0];
for(int i = 0;i <= 2;i++) {
diceRow[i] = diceRow[i + 1];
}
diceRow[3] = top;
makeRowCopy(tempX, tempY);
}
// 서
else if (dir == 2) {
int bottom = diceRow[3];
for(int i = 3;i >= 1;i--) {
diceRow[i] = diceRow[i - 1];
}
diceRow[0] = bottom;
makeRowCopy(tempX, tempY);
}
// 북
else if (dir == 3) {
int bottom = diceCol[3];
for(int i = 3;i >= 1;i--) {
diceCol[i] = diceCol[i - 1];
}
diceCol[0] = bottom;
makeColCopy(tempX, tempY);
}
// 남
else if (dir == 4) {
int top = diceCol[0];
for(int i = 0;i <= 2;i++) {
diceCol[i] = diceCol[i + 1];
}
diceCol[3] = top;
makeColCopy(tempX, tempY);
}
// 아래쪽 값 출력
cout<<diceCol[3]<<"\n";
X = tempX;
Y = tempY;
}
}
크게 어렵지 않게 풀 수 있으나 주사위 회전에 대해 감을 못 잡는다면 삽질할 수도 있을만한 문제인듯하다.
'ALGORITHM > c&c++ baekjoon' 카테고리의 다른 글
[C++/11559] puyo puyo - using simulation (0) | 2023.08.15 |
---|---|
[C++/14502] 연구소 - using BFS (0) | 2023.01.09 |
DP + LCS Algorithm에 대한 이해: 최장 공통 부분 수열 (Longest common subsequence problem) (0) | 2022.06.14 |
음수 간선을 가지는 그래프의 최단 경로: 벨만-포드 알고리즘 (0) | 2022.05.20 |
[C++/1697, 11779] 탐색 중 이전 값를 저장해야 하는 유형의 문제들 (0) | 2022.05.17 |