BOJ 14499 주사위 굴리기

문제출저


풀이

시뮬레이션 문제는 문제를 잘 이해하고, 단계를 잘 나누서 구현하는게 관건인것 같다.(대부분의 알고리즘의 문제가 그렇긴 하지만)
어떤 자료구조를 이용해서 풀이 단계를 구조화하면 나머지는 코드를 작성하는것만 남는다.

정육면체의 주사위를 각 분면의 값을 담는 자료구조로 int형 배열을 이용했다. -> int[] dice = new int[6]
그리고 다음과 같이 문제를 푸는 단계를 나누어서 구현하였다.

1. 주사위를 동, 서, 남, 북으로 회전시켰을때 int형 배열 dice의 값이 어떻게 바뀌는지 확인한다.
예를 들어, 아래 그림을 보면 상단의 주사위 전개도가 초기값이라고 할 경우,
이 주사위를 동쪽으로 회전시키면 하단의 주사위 전개도로 바뀌고, dice 배열의 값들도 달라지게 된다.

content01

동쪽으로 주사위를 회전시키는 함수를 작성하면 다음과 같이 될것이다.
swap 함수는 dice 배열에서 매개변수로 입력받은 인덱스값으로 값의 위치를 바꾸는 함수이다.

	public boolean rotateForEast() {
		swap(1, 5);
		swap(3, 4);
		swap(4, 5);
		return true;
	}  

나머지 3개의 방향 서,남,북도 동일하게 회전시 변경되는 주사위값이 dice배열에 업데이트되도록 함수를 작성해주었다.

2. 주사위의 위치를 업데이트 해준다.
문제에서, 주사위는 지도의 바깥으로 회전시킬 수 없다고 언급되있다.
따라서 주사위가 다음방향으로 회전시킬 수 있는지 없는지를 확인한다음 주사위의 위치를 업데이트 해주었다.

 	public boolean rotateForEast() {
		Pos nextPos = new Pos(dicePos.getY(), dicePos.getX() + 1);
		if (!isAccessible(nextPos)) {
			return false;
		}
		dicePos = nextPos;
		swap(1, 5);
		swap(3, 4);
		swap(4, 5);
		return true;
	}  

3. 최종적으로 주사위의 바닥값을 업데이트 시켜준다. 주사위를 굴렸을대, 이동한 칸에 써있는 수가 0이면, 주사위의 바닥면에 써있는 수를 칸에 복사시키고,
0이 아닌 경우에는 칸에 써있는 수가 주사위의 바닥면으로 복사되며 칸에 써 있는 수는 0이 된다.
그래서 다음과 같이 updateBottom()함수를 만들어서 이용하였다.

   	public boolean isMapEmpty() {
		return map[dicePos.getY()][dicePos.getX()] == 0;
	}

	public void updateBottom() {
		if (isMapEmpty()) {
			map[dicePos.getY()][dicePos.getX()] = dice[BOTTOM];
		} else {
			dice[BOTTOM] = map[dicePos.getY()][dicePos.getX()];
			map[dicePos.getY()][dicePos.getX()] = 0;
		}
	}

이 문제에서 주의할 점은 초기에 주사위의 위치가 (x, y)값으로 주어지는데, 여기서 x가 y값이 되고 y가 x값이 된다는것이였다. (우리가 일반적으로 생각하는 좌표값 y,x와는 다른것)
이게 오해의 소지가 되어 x를 좌표의 x값에 넣고 y를 y에 넣도록 해서 처음에 조금 해맸는데, y에 x값을 넣어주고 x에 y값을 넣어주어야 한다.


소스코드

소스코드