BFS로 접근했습니다.
사이클을 찾는 방법을 몰랐습니다.
방문배열을 백트래킹처럼 지속적으로 리셋시켜 줍니다. 만약 방문한 곳을 다시 방문했다면
사이클이 됩니다.이 문제는 방문한 칸을 계속 방문할 수 있기 때문에
boolean의 visit배열보다 dp로 확인하는 게 좋습니다.
똑같은 (x,y)로 방문하더라도 더 높은 횟수로 방문하는 게 이득
입니다. 그렇기 때문에 갈 수 있지만 더 낮은 곳은 방문하지 않습니다.
if(dp[nx][ny] < dp[x][y]+1){
dp[nx][ny] = dp[x][y] +1;
}
import java.util.*;
import java.io.*;
import java.math.*;
public class Main {
static int[] dx = {0,1,0,-1};
static int[] dy = {1,0,-1,0};
static int maxVal = Integer.MIN_VALUE;
public static void main(String[] args) throws Exception{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int N = Integer.parseInt(st.nextToken());
int M = Integer.parseInt(st.nextToken());
char[][] board = new char[N][M];
for (int i = 0; i < N; i++) {
board[i] = br.readLine().toCharArray();
}
int[] now = {0,0};
boolean[][] v = new boolean[N][M];
v[0][0] = true;
int[][] dp = new int[N][M];
int cnt = 1;
if(DFS(N,M,now, board, v, cnt, dp)) {
System.out.println(-1);
}else {
System.out.println(maxVal);
}
}
public static boolean DFS(int N, int M, int[] now, char[][] board, boolean[][] v, int cnt, int[][] dp) {
maxVal = Math.max(maxVal, cnt);
int multiple = board[now[0]][now[1]] -'0';
for (int d = 0; d < 4; d++) {
int nx = now[0] + dx[d]*multiple;
int ny = now[1] + dy[d]*multiple;
if(0 <= nx && nx < N && 0 <= ny && ny < M && board[nx][ny] != 'H'
&& dp[nx][ny] < dp[now[0]][now[1]]+1) {
if(v[nx][ny]) return true; // 사이클 발견
dp[nx][ny] = dp[now[0]][now[1]] +1; // 더 높은 값으로 업데이트
v[nx][ny] = true; // 방문표시
if(DFS(N,M,new int[] {nx,ny},board,v,cnt+1,dp)) return true;
v[nx][ny] = false; // 방문배열 초기화
}
}
return false;
}
}