알고리즘 모음(C++)

백준 14499 - 주사위 굴리기(C++) 본문

백준

백준 14499 - 주사위 굴리기(C++)

공대생의 잡다한 사전 2022. 1. 4. 21:53

문제 링크입니다. 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개의 줄에 지

www.acmicpc.net

삼성 SW 역량테스트 기출문제 입니다.

복잡해 보여도 규칙만 알면 매우 간단한 문제였습니다.

문제 조건
출력 예시

문제의 핵심은 주사위 움직임을 어떻게 구현하는가 입니다.

저는 주사위의 위치에 순서를 정하고, 동서남북 방향으로 굴렸을 때, 어떻게 변하는지는 확인했습니다.

사진을 통해 설명하겠습니다.

동서남북 이동시 주사위의 변화

해당 사진을 보았을 때, 동서남북 방향으로 굴렸을 때, X위치 주사위의 값이 어떤 값으로 변하는지를 알 수 있습니다.

예를 들어, 1위치의 값은, 동쪽으로 돌렸을 때, 이전 위치의 4의 값으로 변함을 알 수 있습니다.

해당 방법을 통해, 주사위 값의 변화를 구현했습니다.

 

1. 주사위의 값 변화 구현하기

int dice_move[4][7] = { // 0번째 배열은 안쓰는 칸
	{ 0,4,2,1,6,5,3 },  // 동
	{ 0,3,2,6,1,5,4 },  // 서
	{ 0,5,1,3,4,6,2 },  // 북
	{ 0,2,6,3,4,1,5 }   // 남
};
int next_dice[7];           // 다음 주사위값을 복사, 1 ~ 6칸 까지만 사용

void new_dice(int way) {
	for (int i = 1; i <= 6; i++) {
		next_dice[i] = dice[dice_move[way - 1][i]];
	}
	for (int i = 1; i <= 6; i++) {
		dice[i] = next_dice[i];
	}
}

해당 코드를 통해, 움직인 후의 주사위의 값을 구했습니다.

 

 

2. 주사위 움직이기

void move_dice(int x, int y, int way){
	new_dice(way);
	if (map[x][y] == 0) {
		map[x][y] = dice[6];
	}
	else {
		dice[6] = map[x][y];
		map[x][y] = 0;
	}
	cout << dice[1] << "\n";
}

주사위를 움직였을 때, 주사위 아래 값이 변합니다.

따라서 dice[6]의 값을 조정해주고, 맨 위의 값인 dice[1]을 출력해줍니다.

 

 

문제 접근 방법

1. 현재 위치에서 움직였을때, 좌표 구하기

2. 좌표의 범위가 맞다면, 주사위 값을 바꾼뒤 움직이기

3. K번만큼 반복하기

 

 

자세한 것은 코드를 참고해주세요

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <vector>
#include <stack>
#include <cmath>
#include <cstring>

using namespace std;

int N, M, X, Y, K;
int map[21][21];
vector<int> order;
int dice_move[4][7] = { // 0번째 배열은 안쓰는 칸
	{ 0,4,2,1,6,5,3 },  // 동
	{ 0,3,2,6,1,5,4 },  // 서
	{ 0,5,1,3,4,6,2 },  // 북
	{ 0,2,6,3,4,1,5 }   // 남
};
int dx[5] = { 0,0,0,-1,1 }; // dx[0]는 안쓰는 칸
int dy[5] = { 0,1,-1,0,0 }; // dy[0]는 안쓰는 칸
int dice[7];                // 1 ~ 6칸 까지만 사용
int next_dice[7];           // 다음 주사위값을 복사, 1 ~ 6칸 까지만 사용

void new_dice(int way) {
	for (int i = 1; i <= 6; i++) {
		next_dice[i] = dice[dice_move[way - 1][i]];
	}
	for (int i = 1; i <= 6; i++) {
		dice[i] = next_dice[i];
	}
}

void move_dice(int x, int y, int way){
	new_dice(way);
	if (map[x][y] == 0) {
		map[x][y] = dice[6];
	}
	else {
		dice[6] = map[x][y];
		map[x][y] = 0;
	}
	cout << dice[1] << "\n";
}

void solve() {
	int x = X + 1;
	int y = Y + 1;
	for (int i = 0; i < order.size(); i++) {
		int xx = x + dx[order[i]];
		int yy = y + dy[order[i]];
		if (xx >= 1 && xx <= N && yy >= 1 && yy <= M) {
			move_dice(xx,yy, order[i]);
			x = xx;
			y = yy;
		}
	}
}

int main() {
	cin.tie(0);
	cout.tie(0);
	cin >> N >> M >> X >> Y >> K;
	for (int i = 1; i <= N; i++) {
		for (int j = 1; j <= M; j++) {
			cin >> map[i][j];
		}
	}
	for (int i = 1; i <= K; i++) {
		int x;
		cin >> x;
		order.push_back(x);
	}
	solve();
	return 0;
}

 

 

질문 및 조언 댓글 남겨주세요!