슈뢰딩거의 고등어

[백준] 23288 주사위 굴리기 본문

알고리즘

[백준] 23288 주사위 굴리기

슈뢰딩거의 고등어 2022. 1. 17. 01:51

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

 

23288번: 주사위 굴리기 2

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

www.acmicpc.net

 

1. 주사위를 이동방향으로 한칸 굴려 이동시킨다.

- 초기 이동방향은 동쪽

- 이동시키려는 위치가 맵의 바깥일 경우, 반대쪽으로 방향을 바꿔 굴린다.

- 굴릴 경우, 주사위의 각 면의 숫자가 바뀌기 때문에, roll_dice 함수를 사용하여 주사위를 각 면을 회전방향에 따라 다르게 변경해준다.

 

2. 주사위가 도착한 칸에 대한 점수를 획득한다.

- 점수 계산 방식은 주사위가 위치한 칸(x, y)가 가진 수를 b 

- (x,y) 에서 동서남북방향으로 연속해서 이동할 수 있는 칸의 수 C (이동 가능조건: b의 수를 가지고 있는 칸)

- 점수:  b*c 

 

3. 이동방향을 결정한다.

- A : 주사위 아래부분의 수와 B: 현재 칸의 수를 비교한다.

- A > B : 시계방향으로 90도 이동방향을 회전한다. (동남서북)

- A < B : 반시계방향으로 90도 이동방향을 회전한다. (동북서남)

- 같을 경우 유지

 

1~3 을 k 번 반복하여 획득한 점수를 출력한다.

#include <iostream>
#include <queue>
using namespace std;

// 0, 1, 2, 3 동 남 서 북
const int dy[] = {0, 1, 0, -1};
const int dx[] = {1, 0, -1, 0};

int dice[7];
int n, m, score;
int map[21][21];
int k;
int x, y, dir;

void roll_dice(int d) {
	int d1, d2, d3, d4, d5, d6;

	d1 = dice[1], d2 = dice[2], d3 = dice[3];
	d4 = dice[4], d5 = dice[5], d6 = dice[6];
	// 동
	if(d == 0) {
		dice[1] = d4;
		dice[4] = d6;
		dice[6] = d3;
		dice[3] = d1;
	}
	// 남
	else if(d == 1) {
		dice[5] = d1;
		dice[1] = d2;
		dice[2] = d6;
		dice[6] = d5;
	}
	// 서
	else if(d== 2) {
		dice[4] = d1;
		dice[6] = d4;
		dice[3] = d6;
		dice[1] = d3;
	}
	// 북
	else if(d == 3) {
		dice[1] = d5;
        dice[2] = d1;
        dice[6] = d2;
        dice[5] = d6;
	}
}

int bfs (int y, int x, int b) {
	int ret = 0;
	bool visit[21][21] = {false,};

	queue <pair<int, int>> q;
	q.push(make_pair(y,x));
	visit[y][x] = true;

	while(!q.empty()) {

		int cy = q.front().first;
		int cx = q.front().second;
		q.pop();
		ret++;

		for(int i=0; i<4; i++) {
			int ny = cy + dy[i];
			int nx = cx + dx[i];

			if(ny < 1 || nx < 1 || ny > n || nx > m ||visit[ny][nx]) continue;
			if(map[ny][nx] != b) continue;

			visit[ny][nx] = true;
			q.push(make_pair(ny, nx));
		}

	}
	return ret * b;
}


void solve() {

	int ny = y + dy[dir];
	int nx = x + dx[dir];

	if(ny < 1 || nx < 1 || ny > n || nx > m) {
		dir = (dir+2) % 4;
		ny = y + dy[dir];
		nx = x + dx[dir];
	}
	//printf("dir : %d", dir);
	roll_dice(dir);

	score += bfs(ny, nx, map[ny][nx]);
	
	int b = map[ny][nx];
	int a = dice[6];
	if (a > b)
		dir = (dir+1) % 4;
	else if(a < b)
		dir = (dir+3) % 4;

	y = ny;
	x = nx;

}


int main() {
	scanf("%d %d %d", &n, &m, &k);

	for(int i=1; i<=n; i++)
		for(int j=1; j<=m; j++)
			scanf("%d", &map[i][j]);

	x = 1; y = 1; dir = 0;

	for(int i=1; i<7; i++)
		dice[i] = i;
	
	while(k--) {
		solve();
	}

	printf("%d\n", score);

}

'알고리즘' 카테고리의 다른 글

[백준] 1978 소수 찾기  (0) 2022.01.18
[백준] 20061 모노미노도미노2  (0) 2022.01.17
[백준] 19238 스타트택시  (0) 2022.01.17
[BOJ] 17779 게리맨더링 2 (c++)  (0) 2022.01.13
[BOJ] 17822 원판돌리기 (c++)  (0) 2022.01.13
Comments