거의 알고리즘 일기장

백준 14499번 _ 주사위 굴리기 본문

알고리즘 문제풀이

백준 14499번 _ 주사위 굴리기

건우권 2020. 4. 24. 14:14

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

 

14499번: 주사위 굴리기

첫째 줄에 지도의 세로 크기 N, 가로 크기 M (1 ≤ N, M ≤ 20), 주사위를 놓은 곳의 좌표 x y(0 ≤ x ≤ N-1, 0 ≤ y ≤ M-1), 그리고 명령의 개수 K (1 ≤ K ≤ 1,000)가 주어진다. 둘째 줄부터 N개의 줄에 지도에 쓰여 있는 수가 북쪽부터 남쪽으로, 각 줄은 서쪽부터 동쪽 순서대로 주어진다. 주사위를 놓은 칸에 쓰여 있는 수는 항상 0이다. 지도의 각 칸에 쓰여 있는 수는 10을 넘지 않는 자연수 또는 0이다. 마

www.acmicpc.net

풀이방법

주사위를 동서남북으로 옮겼을때 어떻게 할것인지 그려보자. 안에있는게 idx다.

그렸으면 이제 간단하다. 각각 동, 서, 남, 북으로 옮기라는 명령이 나오면 새로운 vector를 만들어 거기다가 저장하고 다시 dice에 move시킨다. (밑에 코드참조)

if (order == 1)
{
	changeDice[2] = dice[2];
	changeDice[4] = dice[6];
	changeDice[1] = dice[4];
	changeDice[3] = dice[1];
	changeDice[5] = dice[5];
	changeDice[6] = dice[3];
}
...
dice = move(changeDice);

 

 

주의할 사항으로는 들어오는 x, y가 각각 북에서 떨어진 값, 서에서 떨어진 값으로 우리가 아는 y,x 순이라는것을 명심해야한다.


전체코드

#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

int board[22][22];
//바닥 idx =6, 위 idx = 1 고정
vector<int> dice;
int N, M, K, x, y;
vector<int> orders;
int dy[] = { 0, 0, 0, -1, 1 };
int dx[] = { 0, 1, -1, 0, 0 };

void Input()
{
	cin >> N >> M >> y >> x >> K;
	int value;
	for (int i = 0; i < N; i++)
	{
		for (int j = 0; j < M; j++)
		{
			cin >> value;
			board[i][j] = value;
		}
	}
	int order;
	for (int i = 0; i < K; i++)
	{
		cin >> order;
		orders.push_back(order);
	}
	dice.resize(7);
}

bool inRange(int ny, int nx)
{
	if (ny >= 0 && nx >= 0 && ny < N && nx < M)
		return true;
	return false;
}

void changDicePos(int order)
{
	vector<int> changeDice = dice;
	if (order == 1)
	{
		changeDice[2] = dice[2];
		changeDice[4] = dice[6];
		changeDice[1] = dice[4];
		changeDice[3] = dice[1];
		changeDice[5] = dice[5];
		changeDice[6] = dice[3];
	}
	else if (order == 2)
	{
		changeDice[2] = dice[2];
		changeDice[4] = dice[1];
		changeDice[1] = dice[3];
		changeDice[3] = dice[6];
		changeDice[5] = dice[5];
		changeDice[6] = dice[4];
	}
	else if (order == 3)
	{
		changeDice[2] = dice[1];
		changeDice[4] = dice[4];
		changeDice[1] = dice[5];
		changeDice[3] = dice[3];
		changeDice[5] = dice[6];
		changeDice[6] = dice[2];
	}
	else if (order == 4)
	{
		changeDice[2] = dice[6];
		changeDice[4] = dice[4];
		changeDice[1] = dice[2];
		changeDice[3] = dice[3];
		changeDice[5] = dice[1];
		changeDice[6] = dice[5];
	}
	dice = move(changeDice);
}

void diceCopy(int ny, int nx)
{
	//1. 이동한 칸에 쓰여있는 수가 0이면 주사위
	//바닥면에 쓰여있는 수가 칸에 복사
	if (board[ny][nx] == 0)
	{
		board[ny][nx] = dice[6];
	}
	//2. 0이 아닌 경우에는 칸에 쓰여있는 수가
	//주사위 바닥면에 복사, 칸에 쓰여있는 수는 0
	else
	{
		dice[6] = board[ny][nx];
		board[ny][nx] = 0;
	}
}

void moveDice(int order)
{
	int ny = y + dy[order];
	int nx = x + dx[order];

	//범위를 넘어서면
	if (inRange(ny, nx) == false)
		return;
	
	//dice 위치 바꾸기
	changDicePos(order);

	//주사위와 보드의 작용 
	diceCopy(ny, nx);
	
	//주사위 상단의 값 출력
	cout << dice[1] << endl;

	//x, y값 교체
	x = nx; y = ny;
}

void solve()
{
	for (auto& order : orders)
	{
		moveDice(order);
	}
}

int main()
{
	Input();
	solve();
	return 0;
}

후기

주사위가 움직일때 위, 아래가 어떻게 바뀌고 어떻게 구현할것인지만 명확하게 생각한다면 어렵지않다.

반응형
Comments