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
<입력>
0. N, M, X, Y(주사위의 초기 위치), k
1. N*M 크기의 지도가 입력으로 들어온다.
2. 주사위의 이동방향이 입력으로 k개 들어온다.
<규칙>
주사위는 주어진 이동방향으로 굴러서 이동하며
1. 이동후 칸의 숫자가 0이면 주사위의 바닥면의 숫자가 칸으로 복사된다.
2. 칸의 숫자가 0이 아니면 칸에 쓰여 있는 숫자가 바닥면으로 복사된다. 그리고 칸의 숫자는 0으로 수정
3. 지도의 바깥으로 이동시키는 명령이 주어지면 무시한다.
4. 이동할 때마다 주사위 윗 면에 쓰여있는 수를 출력한다.
<출력>
이동할 때마다 주사위의 윗면을 가르킨다.
구현이 귀찮은 문제로 주사위의 각 면을 배열의 원소로 설정하고,
주사위를 위로 굴리는 경우, 주사위 면의 변화,
주사위를 오른쪽으로 굴리는 경우, 주사위 면의 변화를 함수로 설정해서 구현했다.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <memory.h>
using namespace std;
int map[21][21];
int command[1000];
int n, m, x, y, k, i, j;
struct dice {
int plane[7] = {0, };
void roll_up() {
int tmp_plane[7] = { 0, };
tmp_plane[1] = plane[5];
tmp_plane[2] = plane[1];
tmp_plane[3] = plane[3];
tmp_plane[4] = plane[4];
tmp_plane[5] = plane[6];
tmp_plane[6] = plane[2];
memcpy(plane, tmp_plane, sizeof(plane));
}
void roll_right() {
int tmp_plane[7] = { 0, };
tmp_plane[1] = plane[4];
tmp_plane[2] = plane[2];
tmp_plane[3] = plane[1];
tmp_plane[4] = plane[6];
tmp_plane[5] = plane[5];
tmp_plane[6] = plane[3];
memcpy(plane, tmp_plane, sizeof(plane));
}
void update_map() {
if (map[x][y] == 0) {
map[x][y] = plane[6];
}
else {
plane[6] = map[x][y];
map[x][y] = 0;
}
}
} dice;
int check_validity(int x, int y) {
if (x == n || x < 0)
return 0;
if (y == m || y < 0)
return 0;
return 1;
}
int main(void) {
scanf("%d %d %d %d %d ", &n, &m, &x, &y, &k);
for (i = 0; i < n; i++) {
for (j = 0; j < m; j++) {
scanf("%d", &map[i][j]);
}
//getchar();
}
for (i = 0; i < k; i++)
scanf("%d", &command[i]);
getchar();
// 규칙 1. 이동후 칸의 숫자가 0이면 주사위의 바닥면의 숫자가 칸으로 복사된다.
// 규칙 2. 칸의 숫자가 0이 아니면 칸에 쓰여 있는 숫자가 바닥면으로 복사된다.
// 규칙 3. 지도의 바깥으로 이동시키는 명령이 주어지면 무시한다.
// 이동할 때마다 주사위 윗 면에 쓰여있는 수를 출력한다.
for (i = 0; i < k; i++) {
switch (command[i]) {
case 1:
if (!check_validity(x, y + 1)) continue;
y++;
dice.roll_right();
break;
case 2:
if (!check_validity(x, y - 1)) continue;
y--;
for(j=0;j<3;j++) dice.roll_right();
break;
case 3:
if (!check_validity(x - 1, y)) continue;
x--;
dice.roll_up();
break;
case 4:
if (!check_validity(x + 1, y)) continue;
x++;
for (j = 0; j < 3; j++) dice.roll_up();
break;
}
dice.update_map();
printf("%d\n", dice.plane[1]);
}
return 0;
}
'Problem Solving > 백준 1일 1커밋' 카테고리의 다른 글
백준 23888 등차수열과 쿼리 (0) | 2022.01.06 |
---|---|
백준 13458 시험 감독 (0) | 2022.01.05 |
백준 14501 퇴사 (0) | 2022.01.05 |
백준 3190 뱀 (1) | 2022.01.04 |
백준 12100 2048 (Easy) (3) | 2022.01.03 |