본문 바로가기

Algorithm/문제

[백준 / JAVA] 23288. 주사위 굴리기2 (G3)

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

 

주사위 굴리기를 잘 풀었다면 약간의 변형으로 해결 가능한 보너스 느낌의 문제다. BFS가 추가되었다고 랭크가 하나 오른 것 같은데 사실 BFS보다 주사위 로직 구현이 더 어렵다고 생각하기에 후자를 구현할 사람은 전자도 구현할 수 있지 않을까? 

 

한마디로 날먹했다는 것

 

import java.util.*;
import java.io.*;

public class Main {
	static BufferedReader br;
	static StringTokenizer st;
	static StringBuilder sb;

	public static void main(String[] args) throws Exception {
		br = new BufferedReader(new InputStreamReader(System.in));
		st = new StringTokenizer(br.readLine());
		N = Integer.parseInt(st.nextToken());
		M = Integer.parseInt(st.nextToken());
		int k = Integer.parseInt(st.nextToken());
		map = new int[N][M];
		for (int i = 0; i < N; i++) {
			st = new StringTokenizer(br.readLine());
			for (int j = 0; j < M; j++)
				map[i][j] = Integer.parseInt(st.nextToken());
		}
		int score = 0;
		for (int i = 0; i < k; i++)
			score += (roll());
		System.out.println(score);
	}

	static int dir = 0, N, M, diceRow = 0, diceCol = 0, map[][],
			dice[][] = { { 0, 2, 0 }, { 4, 1, 3 }, { 0, 5, 0 }, { 0, 6, 0 } }, dr[] = { 0, 1, 0, -1 },
			dc[] = { 1, 0, -1, 0 };

	static int calcScore(int row, int col) {
		int score = map[row][col];
		int count = 0;
		boolean visited[][] = new boolean[N][M];
		Deque<Point> q = new ArrayDeque<>();
		q.add(new Point(row, col));
		visited[row][col]=true;
		while (!q.isEmpty()) {
			Point cur = q.poll();
			count++;
			for (int d = 0; d < 4; d++) {
				int nr = cur.row + dr[d];
				int nc = cur.col + dc[d];
				if (nr < 0 || nc < 0 || nr >= N || nc >= M || map[nr][nc] != score || visited[nr][nc])
					continue;
				q.add(new Point(nr, nc));
				visited[nr][nc]=true;
			}
		}
		return score * count;
	}

	static int roll() {
		int nr = diceRow + dr[dir];
		int nc = diceCol + dc[dir];
		if (nr < 0 || nc < 0 || nr >= N || nc >= M) { // 지도 밖
			nr = diceRow - dr[dir];
			nc = diceCol - dc[dir];
			dir = (dir + 2) % 4;
		}
		diceRow = nr;
		diceCol = nc;
		int top = dice[1][1];
		switch (dir) {
		case 0: // 동
			dice[1][1] = dice[1][0];
			dice[1][0] = dice[3][1];
			dice[3][1] = dice[1][2];
			dice[1][2] = top;
			break;
		case 1: // 남
			dice[1][1] = dice[0][1];
			dice[0][1] = dice[3][1];
			dice[3][1] = dice[2][1];
			dice[2][1] = top;
			break;
		case 2: // 서
			dice[1][1] = dice[1][2];
			dice[1][2] = dice[3][1];
			dice[3][1] = dice[1][0];
			dice[1][0] = top;
			break;
		case 3: // 북
			dice[1][1] = dice[2][1];
			dice[2][1] = dice[3][1];
			dice[3][1] = dice[0][1];
			dice[0][1] = top;
			break;
		}
		if (map[nr][nc] < dice[3][1])
			dir = (dir + 1) % 4;
		else if (map[nr][nc] > dice[3][1])
			dir = (dir + 3) % 4;
		return calcScore(nr, nc);
	}

	static class Point {
		int row, col;

		public Point(int row, int col) {
			super();
			this.row = row;
			this.col = col;
		}
	}
}