알고리즘 공부/C++

[G4] 백준 14499번 주사위 굴리기 C++ 구현, 시뮬레이션

마달랭 2024. 11. 5. 12:01
반응형

리뷰

 

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

맵 상에서 주사위를 굴려 맵과 주사위의 정보를 변경하고, 유효한 굴림 마다 주사위의 위쪽에 저장된 값을 출력하는 문제

처음엔 각 구른 상태를 적절히 더하거나 빼주어 모듈러 연산을 하려 했으나 값이 일치하지 않았다.

결국 전개도를 펼쳐 구현하였는데 오히려 이게 더 쉽고 빨랐던 것 같다.

 

 

전역 변수

  • dx, dy : 주사위가 맵 상에서 움직이는 것을 구현하기 위한 방향 배열
  • lst : 맵 정보를 입력 받을 정수형 2차 배열, 20 * 20 크기로 초기화 해준다.
  • n, m : 맵의 세로 크기n, 맵의 가로 크기 m
  • sx, sy : 주사위의 시작 지점 x, y좌표를 받기 위한 변수
  • k : 주사위를 굴릴 쿼리의 개수
  • dice : 주사위의 각 면의 값을 저장할 정수형 배열, 크기를 7로 초기화 해준다.
  • rev : 주사위의 반대편 면의 인덱스를 저장할 정수형 배열, 하드코딩 해준다.
  • status : 주사위의 전개도 정보를 나타낼 배열, 초기 값은 문제에 나와 있는 대로 하드코딩 해준다.

 

함수

1. roll

void roll(int order)

 

주사위를 굴리는 시뮬레이션을 진행할 함수

  1. 매개 변수로 주어진 order 정보를 입력 받는다.
  2. 각 order에 맞게 전개도를 회전시켜 값을 구해준다.

 

문제풀이

  1. n, m, sx, sy, k값을 각각의 변수에 입력 받아준다.
  2. n * m 크기의 맵 정보를 lst배열에 입력 받아준다.
  3. 초기 주사위의 바닥은 floor이므로 1로 초기화 해준다.
  4. k번의 반복문을 수행하고 각각의 케이스 마다 order에 입력을 받아준다.
  5. 방향 배열을 통해 이동할 위치를 구하고, 만약 맵 범위를 벗어나지 않는다면 이동을 진행해 준다.
  6. 이동에 성공하였으니 sx, sy를 nx, ny로 초기화 해준다.
  7. roll함수에 order를 전달하여 전개도의 회전 시뮬레이션을 진해앻 준다.
  8. floor는 status배열의 1, 1인덱스로 다시 초기화 해준다.
  9. 만약 맵 상에서의 nx, ny좌표에 값이 저장되어 있다면
  10. 주사위의 floor인덱스의 값을 맵 상의 값으로 저장해 주고, 맵 상의 값을 0으로 바꾸어 준다.
  11. 만약 맵의 값이 0이라면 주사위의 바닥면에 저장된 값을 맵에 복사해 준다.
  12. 바닥에 있는 면의 반대편에 있는 면에 저장된 값을 출력해 주고 줄바꿈을 수행한다.

 

참고 사항

주사위의 초기 위치의 값을 주사위의 면 1에 추가해 줄 필요는 없는 것 같다.

 

 

정답 코드

#include<iostream>
#include<algorithm>
using namespace std;

int dx[] = {0, 0, 0, -1, 1 };
int dy[] = {0, 1, -1, 0, 0 };

int n, m, sx, sy, k;
int lst[20][20];
int dice[7];
int rev[7] = { 0, 6, 5, 4, 3, 2, 1 };
int status[4][3] = {
	{0, 2, 0},
	{4, 1, 3},
	{0, 5, 0},
	{0, 6, 0}
};

void roll(int order) {
	if (order == 1) {
		swap(status[3][1], status[1][0]);
		swap(status[1][0], status[1][1]);
		swap(status[1][1], status[1][2]);
	}
	else if (order == 2) {
		swap(status[3][1], status[1][2]);
		swap(status[1][2], status[1][1]);
		swap(status[1][1], status[1][0]);
	}
	else if (order == 3) {
		swap(status[3][1], status[2][1]);
		swap(status[2][1], status[1][1]);
		swap(status[1][1], status[0][1]);
	}
	else {
		swap(status[3][1], status[0][1]);
		swap(status[0][1], status[1][1]);
		swap(status[1][1], status[2][1]);
	}
}

int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);

	cin >> n >> m >> sx >> sy >> k;
	for (int i = 0; i < n; i++)
		for (int j = 0; j < m; j++) 
			cin >> lst[i][j];

	int floor = 1;
	//dice[floor] = lst[0][0];
	//lst[0][0] = 0;
	while (k--) {
		int order; cin >> order;
		int nx = sx + dx[order], ny = sy + dy[order];
		if (0 <= nx && nx < n && 0 <= ny && ny < m) {
			sx = nx, sy = ny;
			roll(order);
			floor = status[1][1];
			//cout << floor << "\n";
			if (lst[nx][ny]) {
				dice[floor] = lst[nx][ny];
				lst[nx][ny] = 0;
			}
			else lst[nx][ny] = dice[floor];

			cout << dice[rev[floor]] << "\n";
		}
	}
}

 

 

728x90
반응형