접근 방법

배열에 대한 크기를 2칸 더 확장해줬다. 반복문에서 가장 처음에 map[nx][ny]가 블랙홀인지 확인해야 하는데 ArrayIndexOutOfBoundsException 때문에 테두리를 초기에 999로 설정해주었다.

map = new int[N+2][N+2];

//테두리 설정
for(int i=0; i<N+2; i++) {
    map[0][i] = 999;
    map[i][0] = 999;
    map[N+1][i] = 999;
    map[i][N+1] = 999;
}

 

블록의 경우엔 block에 대한 변경 좌표를 미리 설정해주고 벽일 경우는 5번 블록과 같이 처리했다

static int[][] block = 
	{{},
	{1, 3, 0, 2},
	{3,0,1,2},
	{2,0,3,1},
	{1,2,3,0},
	{1,0,3,2}};

행의 인덱스는 각 블록에 대한 인덱스이고, 열은 순서대로 상하좌우에 대한 처리이다.

 

웜홀의 경우는 반복문을 탐색해서 짝 웜홀을 찾으면 다음 위치를 짝 웜홀의 위치로 변경해준다

loop:
for(int i=1; i<=N; i++) {
    for(int j=1; j<=N; j++) {
        if(map[i][j] == map[nx][ny]) {
            if(i==nx && j==ny) continue;
            cx = i; cy = j;
            break loop;
        }
    }
}

 

코드

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Solution {

	static int N, max, sx, sy;
	static int[][] map;
	static int[][] block = {{},
			{1, 3, 0, 2},
			{3,0,1,2},
			{2,0,3,1},
			{1,2,3,0},
			{1,0,3,2}};
			
	static int[] dr = { -1, 1, 0, 0 }, dc = { 0, 0, -1, 1 };

	public static void main(String[] args) throws Exception {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer tokens;

		int T = Integer.parseInt(br.readLine());

		for (int tc = 1; tc <= T; tc++) {
			N = Integer.parseInt(br.readLine());
			map = new int[N+2][N+2];
			
			//테두리 설정
			for(int i=0; i<N+2; i++) {
				map[0][i] = 999;
				map[i][0] = 999;
				map[N+1][i] = 999;
				map[i][N+1] = 999;
			}

			//입력
			for (int i = 1; i <= N; i++) {
				tokens = new StringTokenizer(br.readLine());
				for (int j = 1; j <= N; j++) {
					map[i][j] = Integer.parseInt(tokens.nextToken());
				}
			}
			// -1 블랙홀, 1~5 블록, 6~10 웜홀
			// 모든 0의 위치에 대해 4방향으로 가봄
			max = 0;
			for(int i=1; i<=N; i++) {
				for(int j=1; j<=N; j++) {
					if(map[i][j] == 0) {
						for(int d=0; d<4; d++) {
							sx = i; sy = j;
							move(i, j, d);
						}
					}
				}
			}
			System.out.println("#"+tc+" "+max);

		} // end test case
	}

	private static void move(int cx, int cy, int d) {
		// 점수 >> 벽 || 블록
		int score = 0;

		while (true) {
			// 이동 초기 설정
			int nx = cx + dr[d];
			int ny = cy + dc[d];
			
			// 탈출조건 : 시작위치, 블랙홀
			if ((nx == sx && ny == sy) || map[nx][ny] == -1) {
				max = Math.max(max, score);
				return;
			}
			
			// 벽일 경우
			if (map[nx][ny]==999) { //테두리라면
				// 점수 증가
				score++;
				// 방향 전환
				d = block[5][d];
				// 위치 복원
				cx = nx; cy = ny;
				continue;
			}

			// 0일때 위치 갱신
			if (map[nx][ny] == 0) {
				cx = nx; cy = ny;
				continue; //아래 진행 안함
			}
			
			// 블록일 경우
			else if (1 <= map[nx][ny] && map[nx][ny] <= 5) {
				score++; // 점수 증가
				d = block[map[nx][ny]][d];
				cx = nx; // 위치 갱신
				cy = ny;
			}

			// 웜홀일 경우 다음 위치를 짝 웜홀로 변경
			else if (6 <= map[nx][ny] && map[nx][ny]<= 10) {
				loop:
				for(int i=1; i<=N; i++) {
					for(int j=1; j<=N; j++) {
						if(map[i][j] == map[nx][ny]) {
							if(i==nx && j==ny) continue;
							cx = i; cy = j;
							break loop;
						}
					}
				}
			}
		}
	}
}

풀면서 짜증이 많이 났던 문제였다.

같은 방향으로 연속해서 갈 때 x, y에 대한 설정이 헷갈렸다.