No Rules Rules

주사위 굴리기 2 (feat. 백준, 23288번) 본문

생활/코테

주사위 굴리기 2 (feat. 백준, 23288번)

개발하는 완두콩 2022. 7. 25. 23:47
728x90
반응형

주사위 굴리기 2
https://www.acmicpc.net/problem/23288

 

23288번: 주사위 굴리기 2

크기가 N×M인 지도가 존재한다. 지도의 오른쪽은 동쪽, 위쪽은 북쪽이다. 지도의 좌표는 (r, c)로 나타내며, r는 북쪽으로부터 떨어진 칸의 개수, c는 서쪽으로부터 떨어진 칸의 개수이다. 가장 왼

www.acmicpc.net

반응형
// woohyeon.kim
// https://www.acmicpc.net/problem/23288
#include <iostream>
using namespace std;
int N, M, K, direction, result;
int dx[4], dy[4];
int arr[21][21];
bool visit[21][21];
int dice_up, dice_down, dice_front, dice_back, dice_left, dice_right;
int tmp_up, tmp_down, tmp_front, tmp_back, tmp_left, tmp_right;
inline void go_dice(const int& d) {
	// 북
	if (d == 0)
		tmp_up = dice_front, tmp_down = dice_back, tmp_front = dice_down, tmp_back = dice_up, tmp_left = dice_left, tmp_right = dice_right;
	// 동
	else if (d == 1)
		tmp_up = dice_left, tmp_down = dice_right, tmp_front = dice_front, tmp_back = dice_back, tmp_left = dice_down, tmp_right = dice_up;
	// 남
	else if (d == 2)
		tmp_up = dice_back, tmp_down = dice_front, tmp_front = dice_up, tmp_back = dice_down, tmp_left = dice_left, tmp_right = dice_right;
	// 서
	else
		tmp_up = dice_right, tmp_down = dice_left, tmp_front = dice_front, tmp_back = dice_back, tmp_left = dice_up, tmp_right = dice_down;
	dice_up = tmp_up, dice_down = tmp_down, dice_front = tmp_front, dice_back = tmp_back, dice_left = tmp_left, dice_right = tmp_right;
}
inline int get_same_number_count(int x, int y, int count, int& number) {
	visit[x][y] = true;
	for (int idx = 0, nx, ny; idx < 4; ++idx) {
		nx = x + dx[idx], ny = y + dy[idx];
		if (1 <= nx && nx <= N && 1 <= ny && ny <= M && !visit[nx][ny] && number == arr[nx][ny])
			count = get_same_number_count(nx, ny, count + 1, number);
	}
	return count;
}
inline void solve(int& x, int& y) {
	auto nx = x + dx[direction], ny = y + dy[direction];
	if (nx < 1 || nx > N || ny < 1 || ny > M) {
		if (direction == 0)			direction = 2;
		else if (direction == 1)	direction = 3;
		else if (direction == 2)	direction = 0;
		else						direction = 1;
		nx = x + dx[direction], ny = y + dy[direction];
	}
		
	go_dice(direction);
	x = nx, y = ny;
	if (dice_down > arr[x][y])			direction = (direction + 1) % 4;
	else if (dice_down < arr[x][y])
		if (direction == 0)				direction = 3;
		else							--direction;
	for (int ix = 1, iy; ix <= N; ++ix)
		for (iy = 1; iy <= M; ++iy)
			visit[ix][iy] = false;
	result += (arr[x][y] * get_same_number_count(x, y, 1, arr[x][y]));
}
int main() {
	ios::sync_with_stdio(false), cin.tie(), cout.tie();
	dx[0] = -1, dx[1] = 0, dx[2] = 1, dx[3] = 0;
	dy[0] = 0, dy[1] = 1, dy[2] = 0, dy[3] = -1;
	dice_up = 1, dice_down = 6, dice_front = 5, dice_back = 2, dice_left = 4, dice_right = 3;
	cin >> N >> M >> K;
	for (int ix = 1, iy; ix <= N; ++ix)
		for (iy = 1; iy <= M; ++iy)
			cin >> arr[ix][iy];
	direction = 1, result = 0;
	for (int k = 0, x = 1, y = 1; k < K; ++k) {
		solve(x, y);
	}
	cout << result << endl;
	return 0;
}
// *&)*@*
  1. 주사위의 방향을 틀었을때, 주사위의 정보를 잘 정리하면 됩니다.
  2. 영역을 벗어나는 경우, 주사위를 180도 돌려서 굴려야 합니다.
  3. 같은 값을 갖는 이어진 범위는 bfs, dfs, for문 등의 형태로 구할 수 있습니다.
728x90
반응형
Comments