백준 14499번 : 주사위 굴리기 (알고리즘 c++ 풀이)

SJ Lee·2022년 1월 11일
0
post-custom-banner

https://www.acmicpc.net/problem/14499

문제

크기가 N×M인 지도가 존재한다.
지도의 오른쪽은 동쪽, 위쪽은 북쪽이다.
이 지도의 위에 주사위가 하나 놓여져 있으며, 주사위의 전개도는 아래와 같다.

  2
4 1 3
  5
  6

지도의 좌표는 (r, c)로 나타내며,
r는 북쪽으로부터 떨어진 칸의 개수, c는 서쪽으로부터 떨어진 칸의 개수이다.
(0,0) (0,1)
(1,0) (1,1)

주사위는 지도 위에 윗 면이 1이고, 동쪽을 바라보는 방향이 3인 상태로 놓여져 있으며, 놓여져 있는 곳의 좌표는 (x, y) 이다. 가장 처음에 주사위에는 모든 면에 0이 적혀져 있다.

지도의 각 칸에는 정수가 하나씩 쓰여져 있다.
주사위를 굴렸을 때,

  • 이동한 칸에 쓰여 있는 수가 0이면, 주사위의 바닥면에 쓰여 있는 수가 칸에 복사된다.
  • 0이 아닌 경우에는, 칸에 쓰여 있는 수가 주사위의 바닥면으로 복사되며, 칸에 쓰여 있는 수는 0이 된다.

주사위를 놓은 곳의 좌표와 이동시키는 명령이 주어졌을 때, 주사위가 이동했을 때 마다 상단에 쓰여 있는 값을 구하는 프로그램을 작성하시오.

주사위는 지도의 바깥으로 이동시킬 수 없다. 만약 바깥으로 이동시키려고 하는 경우에는 해당 명령을 무시해야 하며, 출력도 하면 안 된다.


입력

첫째 줄에 지도의 세로 크기 N, 가로 크기 M (1 ≤ N, M ≤ 20), 주사위를 놓은 곳의 좌표 x, y(0 ≤ x ≤ N-1, 0 ≤ y ≤ M-1), 그리고 명령의 개수 K (1 ≤ K ≤ 1,000)가 주어진다.

둘째 줄부터 N개의 줄에 지도에 쓰여 있는 수가 북쪽부터 남쪽으로, 각 줄은 서쪽부터 동쪽 순서대로 주어진다.
주사위를 놓은 칸에 쓰여 있는 수는 항상 0이다.
지도의 각 칸에 쓰여 있는 수는 10 미만의 자연수 또는 0이다.

마지막 줄에는 이동하는 명령이 순서대로 주어진다.
동쪽은 1, 서쪽은 2, 북쪽은 3, 남쪽은 4로 주어진다.


풀이

📍 풀이

시뮬레이션 문제 : 문제의 상황과 조건을 토대로 구현하면 된다.

  • 순서
  1. 주어진 이동명령이 수행 가능한지 (지도 바깥으로 이동하는게 아닌지) 확인
  2. 1이 가능하다면, 주사위 이동
  3. 주사위나 칸에 숫자 복사하기
  4. 주사위 상단에 있는 값 출력하기

    1. 이동명령 수행 가능여부 확인 함수 Judgement

이동명령은 총 4가지, 정수로 주어짐
이동명령 수행 불가능하다면 무시한다.

1=동 → y==M-1 이면 무시
2=서 → y==0 이면 무시
3=북 → x==0 이면 무시
4=남 → x==N-1 이면 무시

무시하게 되는 경우에 return 0 을 해줬다.

if (!Judgement(int d))
	continue;

나중에 위와 같은 조건문을 걸어주면 된다.


    1. 주사위 이동 함수 Movement

주어진 이동방향에 따라서 주사위를 굴린다.
dice라는 1차원 배열을 만들어서, 동서남북 각 방향으로 굴렸을 때의 위치변화를 관찰해 적용한다.
dice배열의 각 요소가 가르키는 바는 다음과 같다.
dice[6] = { 위, 아래, 동, 서, 남, 북 }


    1. 주사위나 칸에 숫자 복사는 함수 Play

실제 주사위를 굴리는 과정이다.
move_order 배열에 담겨있는 이동 명령을 하나씩 수행하며 결과를 출력한다.


    1. 주사위 상단에 있는 값 출력하기

dice배열에서 주사위 상단에 해당하는 요소는 0번째 요소이므로, dice[0]을 출력하면 된다.


📍 코드

#include <iostream>
#define endl "\n"
#define MAX 20
using namespace std;

int N, M, x, y, K;
int map[MAX][MAX];
int move_order[1000];
int dice[6]; //처음엔 전부다 0

int Judgement(int d) {
	if (d == 1) {
		if (y == M - 1) return 0;
	}
	else if (d == 2) {
		if (y == 0) return 0;
	}
	else if (d == 3) {
		if (x == 0) return 0; 
	}
	else if (d == 4) {
		if (x == N - 1) return 0;
	}
	return 1;
}

void Movement(int d) {
	int temp = dice[0];
	if (d == 1) {
		y++;
		dice[0] = dice[3];
		dice[3] = dice[1];
		dice[1] = dice[2];
		dice[2] = temp;
	}
	else if (d == 2) {
		y--;
		dice[0] = dice[2];
		dice[2] = dice[1];
		dice[1] = dice[3];
		dice[3] = temp;
	}
	else if (d == 3) {
		x--;
		dice[0] = dice[4];
		dice[4] = dice[1];
		dice[1] = dice[5];
		dice[5] = temp;
	}
	else if (d == 4) {
		x++;
		dice[0] = dice[5];
		dice[5] = dice[1];
		dice[1] = dice[4];
		dice[4] = temp;
	}
}



void Play() {
	for (int i = 0; i < K; i++) {
		if (!Judgement(move_order[i])) {
			continue;
		}

		Movement(move_order[i]);
		if (map[x][y] == 0) {
			map[x][y] = dice[1];
		}
		else {
			dice[1] = map[x][y];
			map[x][y] = 0;
		}
		cout << dice[0] << endl;
	}
}

int main() {
	// input
	cin >> N >> M >> x >> y >> K;
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < M; j++) {
			cin >> map[i][j];
		}
	}
	for (int i = 0; i < K; i++) 
		cin >> move_order[i];

	Play();
}
post-custom-banner

0개의 댓글