조건을 착실히 따르면 DFS로 어렵지않게 풀 수 있는 문제다.
일반적으로 재귀함수를 구현할 때 다음과 같은 형태로 구현하는 것이 일반적이나
function recursion() {
if(종료조건){...}
현재 깊이에서의 수행
}
이 문제에서는 현재 깊이에서의 수행 안에 종료조건을 배치하는 것이 시작점을 다시 방문해야하는 상황에서의 set과 방문체크 처리를 하기에 용이했다.
function recursion() {
현재 깊이에서의 수행 {
if(종료조건){...}
}
}
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashSet;
import java.util.StringTokenizer;
public class Solution {
static HashSet<Integer> set;
static int[][] dir = {{1, 1}, {1, -1}, {-1, -1}, {-1, 1}};
static boolean[][] visited;
static int[][] map;
static int N, T, ans, cnt;
public static void main(String[] args) throws NumberFormatException, IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = null;
T = Integer.parseInt(br.readLine());
for(int t = 1; t <= T ; ++t) {
N = Integer.parseInt(br.readLine());
set = new HashSet<>();
map = new int[N][N];
visited = new boolean[N][N];
ans = -1;
for(int r = 0 ; r < N ; ++r) {
st = new StringTokenizer(br.readLine());
for(int c = 0 ; c < N ; ++c) {
map[r][c] = Integer.parseInt(st.nextToken());
}
}
for(int r = 0 ; r < N - 2 ; ++r) {
for(int c = 1 ; c < N - 1 ; ++c) {
init();
set.add(map[r][c]);
visited[r][c] = true;
tour(r, c, r, c, 0);
visited[r][c] = false;
set.remove(map[r][c]);
}
}
System.out.println("#" + t + " " + ans);
}
}
private static void tour(int cr, int cc, int sr, int sc, int curve) {
for(int d = curve ; d < 4 ; ++d) {
int nr = cr + dir[d][0];
int nc = cc + dir[d][1];
if(set.size() >= 3 && nr == sr && nc == sc) {
cnt = set.size();
ans = cnt > ans ? cnt : ans;
return;
}
if(nr < 0 || nr >= N || nc < 0 || nc >= N || visited[nr][nc]) continue;
if(set.contains(map[nr][nc])) continue;
visited[nr][nc] = true;
set.add(map[nr][nc]);
tour(nr, nc, sr, sc, d);
set.remove(map[nr][nc]);
visited[nr][nc] = false;
}
}
private static void init() {
set.clear();
for(int r = 0 ; r < N ; ++r) {
for(int c = 0 ; c < N ; ++c) {
visited[r][c] = false;
}
}
}
}