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;
}
}
성능