[백준 14499번] 주사위 굴리기 C++

Andrew·2021년 12월 31일
0

알고리즘연습

목록 보기
3/31

[14499번 주사위 굴리기]
https://www.acmicpc.net/problem/14499

그렇게 어렵지 않은 문제였던 것 같다. 여러 방법이 있겠지만, 필자는 주사위 전개도를 나타내는 2차원 배열 하나 그리고 지도를 나타내는 2차원 배열 하나를 생성하고 풀었다.

풀이 방법

1.

주사위를 왼쪽(위쪽)으로 굴리는 것은 오른쪽(아래쪽)으로 3번 굴리는 것과 같다는 점에서 아이디어를 얻었다(그 역도 성립한다).

2.

명령에 따라 굴리는 방향이 정해지면 그에 맞게 순서가 바뀌는 번호를 Queue에 넣고, 바뀐 순서대로 Queue에서 뽑아내며 다시 대입해준다(꼭 Queue일 필요는 없다).

먼저 오른쪽과 아래쪽으로 굴리는 함수를 정의해주고, 왼쪽과 위쪽은 각각 반대 방향으로 굴리는 함수를 3번 수행하는 함수로 정의해주었다.

3.

이렇게 되면 윗면과 아랫면은 항상 dice[1][1]과 dice[3][1]로 고정이 되어있다. map과 숫자를 주고받은 때는 항상 dice[3][1]로만 해주고, 출력 시 항상 dice[1][1]을 출력해주면 된다.

주의할 점: 분명 문제의 입력에서 n,m,x,y,K 순으로 입력이 주어진다고 되어있으나 실제로는 n,m,y,x,K 순으로 주어진다.

#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <vector>
#include <utility>  // pair
#include <tuple>
#include <stack>
#define ll long long
#define INF 1e9
using namespace std;

int n,m,x,y,K;
int map[20][20];
int dice[4][3];  // top face is dice[1][1], bottom face is dice[3][1] in the first place
int r,c;
int dr[] = {0,0,-1,1};
int dc[] = {1,-1,0,0};
int top, bottom;
queue<int> commands;

void rollDown() {
	queue<int> q;

	q.push(dice[3][1]);
	for(int i=0;i<3;++i) {
		q.push(dice[i][1]);
	}

	dice[0][1] = q.front();
	q.pop();
	for(int i=1;i<4;++i) {
		dice[i][1] = q.front();
		q.pop();
	}
}

void rollUp() {
	for(int i=0;i<3;++i) {
		rollDown();
	}
}

void rollRight() {
	queue<int> q;
	q.push(dice[3][1]);
	for(int i=0;i<3;++i) {
		q.push(dice[1][i]);
	}

	for(int i=0;i<3;++i) {
		int num = q.front();
		q.pop();

		dice[1][i] = num;
	}
	dice[3][1] = q.front();
	q.pop();
}

void rollLeft() {
	for(int i=0;i<3;++i) {
		rollRight();
	}
}

void sol() {
	while(!commands.empty()) {
		int type = commands.front();
		commands.pop();
		int nr, nc;
		nr = r + dr[type-1];
		nc = c + dc[type-1];

		if(nr < 0 || nr >= n || nc < 0 || nc >= m) {
			continue;
		}

		r = nr; c = nc;
		if(dr[type-1] > 0) {
			rollDown();
		} else if(dr[type-1] < 0) {
			rollUp();
		}

		if(dc[type-1] > 0) {
			rollRight();
		} else if(dc[type-1] < 0) {
			rollLeft();
		}


		if(map[r][c] == 0) {
			map[r][c] = dice[3][1];
		} else {
			dice[3][1] = map[r][c];
			map[r][c] = 0;
		}

		cout << dice[1][1] << '\n';
	}
}

int main(void) {
	ios_base :: sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
	cin >> n >> m >> y >> x >> K;
	r = y;
	c = x;
	top = 1; bottom = 3;

	for(int i=0;i<n;++i) {
		for(int j=0;j<m;++j) {
			cin >> map[i][j];
		}
	}
	for(int i=0;i<K;++i) {
		int k;
		cin >> k;
		commands.push(k);
	}

	sol();

	return 0;
}

profile
조금씩 나아지는 중입니다!

0개의 댓글