티스토리 뷰
https://www.acmicpc.net/problem/23288
23288번: 주사위 굴리기 2
크기가 N×M인 지도가 존재한다. 지도의 오른쪽은 동쪽, 위쪽은 북쪽이다. 지도의 좌표는 (r, c)로 나타내며, r는 북쪽으로부터 떨어진 칸의 개수, c는 서쪽으로부터 떨어진 칸의 개수이다. 가장 왼
www.acmicpc.net
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_BOJ_23288 {
static int[] dr= {0,1,0,-1};
static int[] dc= {1,0,-1,0};
static int[] east= {3,1,0,5,4,2};
static int[] west= {2,1,5,0,4,3};
static int[] south= {1,5,2,3,0,4};
static int[] north= {4,0,2,3,5,1};
static int N, M, K;
static int[][] map;
static int[] dices;
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];
dices=new int[6];
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=0; i<6; i++) {
dices[i]=i+1;
}
int r=0, c=0, d=0;
int answer=0;
for (int i=0; i<K; i++) {
r+=dr[d];
c+=dc[d];
if (r<0 || c<0 || r>=N || c>=M) {
r-=dr[d]; c-=dc[d];
d=(d+2)%4;
r+=dr[d]; c+=dc[d];
}
answer+=getScore(r,c);
d=changeDir(d, map[r][c]);
}
System.out.println(answer);
}
private static int getScore(int r, int c) {
int B=map[r][c];
int C=1;
boolean[][] visited=new boolean[N][M];
Queue<int[]> q=new LinkedList<>();
q.add(new int[] {r,c});
visited[r][c]=true;
while (!q.isEmpty()) {
int[] curr=q.poll();
for (int i=0; i<4; i++) {
int nr=curr[0]+dr[i];
int nc=curr[1]+dc[i];
if (nr<0 || nc<0 || nr>=N || nc>=M) continue;
if (!visited[nr][nc] && map[nr][nc]==B) {
C++;
q.add(new int[] {nr,nc});
visited[nr][nc]=true;
}
}
}
return B*C;
}
private static int changeDir(int d, int B) {
int[] temp=new int[6];
if (d==0) {
for (int i=0; i<6; i++) {
temp[i]=dices[east[i]];
}
}
else if (d==1) {
for (int i=0; i<6; i++) {
temp[i]=dices[south[i]];
}
}
else if (d==2) {
for (int i=0; i<6; i++) {
temp[i]=dices[west[i]];
}
}
else if (d==3) {
for (int i=0; i<6; i++) {
temp[i]=dices[north[i]];
}
}
dices=temp;
int A=temp[5]; //바닥면
if (A>B) return (d+1)%4;
else if (A<B) return (d+3)%4;
else return d;
}
}
구현+시뮬레이션+BFS 문제
점수를 얻는 것은 getScore 함수로, BFS를 이용해 구현했다. 미방문인 곳 & 현재 위치와 숫자가 같은 곳만 탐색하여 그 횟수를 세주는 식으로 진행했다.
주사위를 움직이는 것은 changeDir 함수를 통해 구현했다.
dices 배열의 각 자리를 현재 바라보고 있는 방향으로 매칭시켰다.
즉 0 인덱스: 위쪽 방향, 1 인덱스: 북쪽 방향, 2 인덱스: 동쪽 방향, 3 인덱스: 서쪽 방향, 4 인덱스: 남쪽 방향, 5 인덱스: 바닥 방향
이렇게 해서 현재 00방향을 바라보고 있는 것이 동서남북으로 움직일 경우 어느 방향을 바라보고 있을 것인가를 생각해서 이 정보를 이용해 east, west, south, north 배열을 만든 뒤 이를 이용해 dices 배열의 값을 적절하게 넣어주었다.
'Problem Solving' 카테고리의 다른 글
[프로그래머스] N으로 표현 (Java) (0) | 2022.04.23 |
---|---|
[BOJ 17144] 미세먼지 안녕! (Java) (0) | 2022.04.23 |
[BOJ 20061] 모노미노도미노2 (Java) (0) | 2022.04.21 |
[BOJ 21610] 마법사 상어와 비바라기 (Java) (0) | 2022.04.19 |
[BOJ 1520] 내리막 길 (Java) (0) | 2022.04.18 |