본문 바로가기
📊알고리즘/BOJ

BOJ 144999 - 주사위 굴리기

by meteorfish 2024. 4. 1.
728x90

14499번: 주사위 굴리기 (acmicpc.net)

 

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);
	}
}

 

728x90

'📊알고리즘 > 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