2 분 소요

주사위 굴리기 (백준 Gold 4)

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

모든 면이 0인 주사위가 주어지고
특정한 맵 데이터가 주어질 때,
각 움직임마다, 주사위의 ‘위쪽’ 숫자를 출력하는 문제

조건

  • x(0~n-1), y(0~m-1)이 주어짐
  • 명령은 동서북남 순으로 1234 가 매핑됨
  • 주사위가 움직일때의 추가 조건들
    • 주사위가 이동한 후, 위쪽의 숫자가 출력됨
      다만, 이동이 불가능한 위치의 명령이 주어진 경우는
      명령과 출력이 무시됨
    • 주사위가 이동한 칸에 쓰여있는 수가 0이라면,
      바닥값이 해당 위치에 복사됨
      (주사위 -> 맵)
    • 0이 아닌 경우, 주사위의 바닥면으로 복사되고
      해당 칸의 값이 0이됨
      (맵 -> 주사위)
  • 주사위가 시작하는 위치의 값은 0

풀이 방법

나는 주사위에 관련된 클래스를 제작하여 문제를 풀었다
유의할 점은

  • '이동 성공 판정'
  • 방향에 따른 주사위 각 면의 값 교환

이며,
각 방향에 따라 4개의 면의 값들을 수정해주었다

제출 코드

#include<iostream>
#include<vector>

using namespace std;

enum dir
{
	d_Right = 0,
	d_Left,
	d_Up,
	d_Down,
};

int dirY[4] = { 0,0,-1,1 };
int dirX[4] = { 1,-1,0,0 };

int n, m, x, y, k;

class dice
{
public:
	dice(int nowY, int nowX)
	{
		nowPosY = nowY;
		nowPosX = nowX;
	}

	int GetTop() const { return top; }

	bool Roll(vector<vector<int>>& maps, dir d)
	{
		int di = static_cast<int>(d);
		int ny = nowPosY + dirY[di];
		int nx = nowPosX + dirX[di];

		if (ny < 0 || ny >= n ||
			nx < 0 || nx >= m)
			return false;

		// 원본 값들
		int otop = top;
		int odown = down;
		int oright = right;
		int oleft = left;
		int oforward = forward;
		int oback = back;

		switch (d)
		{
		case d_Right: {
			top = oleft;
			right = otop;
			down = oright;
			left = odown;
		}
					break;
		case d_Left: {
			top = oright;
			left = otop;
			down = oleft;
			right = odown;
		}
				   break;
		case d_Up: {
			top = oback;
			back = odown;
			down = oforward;
			forward = otop;
		}
				 break;
		case d_Down: {
			top = oforward;
			forward = odown;
			down = oback;
			back = otop;
		}
				   break;
		}

		if (maps[ny][nx] != 0)
		{
			down = maps[ny][nx];
			maps[ny][nx] = 0;
		}
		else
		{
			maps[ny][nx] = down;
		}
		
		nowPosY = ny;
		nowPosX = nx;

		return true;
	}

protected:
	int nowPosY, nowPosX;

	int top = 0;
	int down = 0;
	int right = 0;
	int left = 0;
	int forward = 0;
	int back = 0;
};

int main()
{
	cin >> n >> m >> y >> x >> k;

	vector<vector<int>> maps(n, vector<int>(m, 0));
	for (int i = 0; i < n; i++)
		for (int j = 0; j < m; j++)
			cin >> maps[i][j];

	dice dic(y, x);

	for (int i = 0; i < k; i++)
	{
		int ord;
		cin >> ord;
		ord--;
		if (dic.Roll(maps, static_cast<dir>(ord)))
		{
			cout << dic.GetTop() << '\n';
		}
	}

	return 0;
}

결과

Image

틀린 부분은 문제의 조건 중
‘이동한 칸에 쓰여 있는 수가 0이면, 주사위의 바닥면에 쓰여 있는 수가 칸에 복사된다’
부분을 구현하지 못하여 틀렸었다

문제를 잘 읽어야 한다…

댓글남기기