Java

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

iheeeee6-6 2023. 6. 8. 00:14
728x90

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

 

23288번: 주사위 굴리기 2

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

www.acmicpc.net

 

주사위 굴리기 1을 풀고 오면 간단히 해결 가능한 문제였다! 주사위 굴리기1에 bfs를 사용하면 된다!!

주사위 굴리기 1은 아래와 같다! 참고하세용

https://iheeeee6-6.tistory.com/123

 

[백준 14499] 주사위 굴리기 (JAVA)

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 ≤

iheeeee6-6.tistory.com

---------------------------------------------------------------------------------------------------------------------------------------------------------------

 

<풀이>

이 문제에서 잘 고려해야 할 사항은 아래의 3가지 이다.

 

1.범위를 벗어나면 반대 방향으로 전진 

2. 그 전진한 위치에서 동서남북으로 연속 이동한 영역의 값과 현재 위치의 값이 동일하면 count를 센 후 (bfs사용)

-> 현재 위치값 *count 를 score 변수에 더해준다. 

3. 현재 위치값과 주사위의 바닥 값에 따라 다음 이동 방향이 정해진다.

이때, 시계방향, 반시계방향으로 바뀌어야 하므로 

첫 스타트 방향인 동쪽을 인덱스 0으로 잡고, 1=남, 2=서, 3=북으로 넣어주었다.

시계방향일 경우에는 현재 방향인덱스+1

반시계일 경우에는 현재 방향인덱스-1을 하면 간단히 해결 가능!

1번의 범위를 벗어나는 반대방향 전진인 것은 +2를 하고 %4로 나머지 값을 구하면 간단히 해결 가능!

 

 

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;

public class Main {
	static int n, m, k, x = 0, y = 0, score = 0, dir = 0;
	static int[] dx = { 0, 1, 0, -1 }; // 0동 1남 2서 3북
	static int[] dy = { 1, 0, -1, 0 };

	//   2
	// 4 1 3 //1이 현재 상단
	//   5
	//   6
	static int[] dice = new int[7];
	static int[][] map; // 지도

	static class Node {
		int x, y;

		Node(int x, int y) {
			this.x = x;
			this.y = y;
		}
	}

	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer(br.readLine());
		n = Integer.parseInt(st.nextToken());
		m = Integer.parseInt(st.nextToken());
		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());
			}
		}

		for(int i=1;i<7;i++) {
			dice[i]=i;
		}
		for (int i = 0; i < k; i++)
			move();

		System.out.println(score);
	}

	static void move() {
		int xx = x + dx[dir];
		int yy = y + dy[dir];

		if (xx >= n || yy >= m || xx < 0 || yy < 0) {
			dir = (dir + 2) % 4;

			xx = x + dx[dir];
			yy = y + dy[dir];
		}

		int[] temp = dice.clone();
		switch (dir) {
		case 0:
			dice[1] = temp[4];
			dice[4] = temp[6];
			dice[6] = temp[3];
			dice[3] = temp[1];
			break;

		case 1:
			dice[6] = temp[5];
			dice[1] = temp[2];
			dice[5] = temp[1];
			dice[2] = temp[6];
			break;

		case 2:
			dice[6] = temp[4];
			dice[1] = temp[3];
			dice[3] = temp[6];
			dice[4] = temp[1];
			break;

		case 3:
			dice[6] = temp[2];
			dice[1] = temp[5];
			dice[5] = temp[6];
			dice[2] = temp[1];
			break;

		}

		x = xx;
		y = yy;

		score += getScore() * map[x][y];

		if (dice[6] > map[xx][yy]) {
			dir += 1;
			if (dir > 3)
				dir = 0;
		} else if (dice[6] < map[xx][yy]) {
			dir -= 1;
			if (dir < 0)
				dir = 3;
		}

	}

	static int getScore() {
		int count = 1;
		Queue<Node> q = new LinkedList<>();
		q.add(new Node(x, y));
		int val = map[x][y];
		boolean[][] visited = new boolean[n][m];
		visited[x][y] = true;
		while (!q.isEmpty()) {
			Node node = q.poll();

			for (int i = 0; i < 4; i++) {
				int xx = node.x + dx[i];
				int yy = node.y + dy[i];
				if (xx < 0 || yy < 0 || xx >= n || yy >= m || visited[xx][yy] || map[xx][yy] != val)
					continue;
				q.add(new Node(xx, yy));
				visited[xx][yy] = true;
				count++;
			}
		}
		return count;
	}
}