본문 바로가기
Algorithm/문제 풀이

[알고리즘] 주사위 굴리기 (백준 14499번)

by Sky Titan 2020. 9. 23.
728x90
 

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

 solved.ac 기준 골드5 문제로 시뮬레이션 문제인데 예전에 풀었을 때는 내가 실력이 별로여서 그런지 모르겠지만 생각을 좀 많이 하고 풀었었는데 이번엔 금방 풀렸다. 사실 그리 어려운 문제도 아니다. 주사위를 어떻게 표현할 것인가가 관건

 

Solution

 주사위는 2차원 배열로 구현했다. 이런 큐브 굴리기 문제는 배열로 구현해서 어느정도 하드코딩 느낌으로 해야되는 것 같다.

 

1. 전역 변수

	static int x, y;
	static int N, M, K;
	static int map[][];
	static int bottom[] = {3, 1}, top[] = {1, 1}, front[] = {0, 1}, rear[] = {2, 1}, left[] = {1, 0}, right[] = {1, 2};
	static int cube[][] = {
			{0, 0, 0},
			{0, 0 ,0},
			{0, 0, 0},
			{0, 0, 0},
	};

 주사위와 나머지 입력값들, 그리고 주사위의 바닥면, 윗면, 앞면, 뒷면, 오른면, 왼면의 위치를 표현하는 배열들을 두었다.


2. 경계 검사

	//경계검사
	static boolean isInBound(int order)
	{
		switch (order)
		{
			//동서북남
			case 1:
				if(y == M - 1)
					return false;
				break;
			case 2:
				if(y == 0)
					return false;
				break;
			case 3:
				if(x == 0)
					return false;
				break;
			case 4:
				if(x == N - 1)
					return false;
				break;
		}
		return true;
	}

 주사위를 굴렸을 때 경계값을 넘어가게 되면 안되기 때문에 경계검사를 한다.

 


3. 주사위 움직이기

//주사위 움직이기
	static void moveCube(int order)
	{
		switch (order)
		{
			//동서남북
			case 1:
				y++;
				break;
			case 2:
				y--;
				break;
			case 3:
				x--;
				break;
			case 4:
				x++;
				break;
		}
	}

4. 주사위 굴리기

//주사위 굴리기
	static void rollCube(int order)
	{
		int temp = 0;
		switch (order)
		{
			//동서북남
			case 1:
				temp = cube[bottom[0]][bottom[1]];
				cube[bottom[0]][bottom[1]] = cube[right[0]][right[1]];
				cube[right[0]][right[1]] = cube[top[0]][top[1]];
				cube[top[0]][top[1]] = cube[left[0]][left[1]];
				cube[left[0]][left[1]] = temp;
				break;
			case 2:
				temp = cube[bottom[0]][bottom[1]];
				cube[bottom[0]][bottom[1]] = cube[left[0]][left[1]];
				cube[left[0]][left[1]] = cube[top[0]][top[1]];
				cube[top[0]][top[1]] = cube[right[0]][right[1]];
				cube[right[0]][right[1]] = temp;
				break;
			case 3:
				temp = cube[front[0]][front[1]];

				for(int i = 0;i < 3;i++)
					cube[i][1] = cube[i + 1][1];
				cube[bottom[0]][bottom[1]] = temp;
				break;
			case 4:
				temp = cube[bottom[0]][bottom[1]];

				for(int i = 3;i >= 1;i--)
					cube[i][1] = cube[i-1][1];
				cube[front[0]][front[1]] = temp;
				break;
		}
	}

 요 부분이 조금 헷갈린다. 머릿 속으로 주사위를 잘 굴려봐야한다.

 

 

전체 코드다.

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;

public class Main {

	static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
	static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

	static int x, y;
	static int N, M, K;
	static int map[][];
	static int bottom[] = {3, 1}, top[] = {1, 1}, front[] = {0, 1}, rear[] = {2, 1}, left[] = {1, 0}, right[] = {1, 2};
	static int cube[][] = {
			{0, 0, 0},
			{0, 0 ,0},
			{0, 0, 0},
			{0, 0, 0},
	};

	public static void solution() throws Exception
	{
		String[] list = br.readLine().split(" ");

		N = Integer.parseInt(list[0]);
		M = Integer.parseInt(list[1]);
		x = Integer.parseInt(list[2]);
		y = Integer.parseInt(list[3]);
		K = Integer.parseInt(list[4]);

		map = new int[N][M];

		for(int i = 0;i < N;i++)
		{
			list = br.readLine().split(" ");
			for(int j = 0;j < M;j++)
				map[i][j] = Integer.parseInt(list[j]);
		}

		String[] order_list = br.readLine().split(" ");

		for(int k = 0;k < K;k++)
		{
			int order = Integer.parseInt(order_list[k]);

			//경계선 안에 있는 경우에만 진행
			if(isInBound(order))
			{
				rollCube(order);
				moveCube(order);

				//맵의 칸이 0이면 -> 주사위 바닥면의 수를 복사
				if(map[x][y] == 0)
				{
					map[x][y] = cube[bottom[0]][bottom[1]];
				}
				//맵의 칸이 0이 아니면 -> 칸의 수를 주사위 바닥면에 복사 -> 칸은 0으로
				else
				{
					cube[bottom[0]][bottom[1]] = map[x][y];
					map[x][y] = 0;
				}
				bw.write(cube[top[0]][top[1]]+"\n");
			}
		}
	}

	//경계검사
	static boolean isInBound(int order)
	{
		switch (order)
		{
			//동서북남
			case 1:
				if(y == M - 1)
					return false;
				break;
			case 2:
				if(y == 0)
					return false;
				break;
			case 3:
				if(x == 0)
					return false;
				break;
			case 4:
				if(x == N - 1)
					return false;
				break;
		}
		return true;
	}

	//주사위 움직이기
	static void moveCube(int order)
	{
		switch (order)
		{
			//동서남북
			case 1:
				y++;
				break;
			case 2:
				y--;
				break;
			case 3:
				x--;
				break;
			case 4:
				x++;
				break;
		}
	}

	//주사위 굴리기
	static void rollCube(int order)
	{
		int temp = 0;
		switch (order)
		{
			//동서북남
			case 1:
				temp = cube[bottom[0]][bottom[1]];
				cube[bottom[0]][bottom[1]] = cube[right[0]][right[1]];
				cube[right[0]][right[1]] = cube[top[0]][top[1]];
				cube[top[0]][top[1]] = cube[left[0]][left[1]];
				cube[left[0]][left[1]] = temp;
				break;
			case 2:
				temp = cube[bottom[0]][bottom[1]];
				cube[bottom[0]][bottom[1]] = cube[left[0]][left[1]];
				cube[left[0]][left[1]] = cube[top[0]][top[1]];
				cube[top[0]][top[1]] = cube[right[0]][right[1]];
				cube[right[0]][right[1]] = temp;
				break;
			case 3:
				temp = cube[front[0]][front[1]];

				for(int i = 0;i < 3;i++)
					cube[i][1] = cube[i + 1][1];
				cube[bottom[0]][bottom[1]] = temp;
				break;
			case 4:
				temp = cube[bottom[0]][bottom[1]];

				for(int i = 3;i >= 1;i--)
					cube[i][1] = cube[i-1][1];
				cube[front[0]][front[1]] = temp;
				break;
		}
	}


	public static void main(String[] args) {
		try
		{
			solution();

			bw.close();
			br.close();
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
	}

}
728x90

댓글