🧫 문제 분석
✔️ 출처
📖 문제

완전탐색 + 백트래킹 문제다.
5가지중 가운데 볼록한 모양을 제외하곤
상하좌우로 탐색하며 탐색한 깊이가 4이면 테트로미노가 만들어진다. 이때 각 수를 max와 비교한다.
가운데 볼록한 모양(키보드 방향키 모양) 은 현 위치에서 상하좌우 4개중 3개를 뽑아서 처리한다.
예를 들어
dx, dy 0, 1, 2 번째 인덱스를 탐색하라고 "012 " 문자열을 만들어서 저장해놓는다는 것이다.
현재 위치에서 dx, dy 만큼 더한 인덱스에 접근하면
ㅓ 모양이 나온다.
🔅 문제 풀이
import java.io.*;
import java.util.*;
public class Main {
static int[] dx = {0, 0, 1, -1};
static int[] dy = {1, -1, 0, 0};
static int[][] graph;
static boolean[][] visited;
static ArrayList<String> list = new ArrayList<>();
static int max = 0;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
StringTokenizer st = new StringTokenizer(br.readLine());
StringBuilder sb = new StringBuilder();
int n = Integer.parseInt(st.nextToken());
int m = Integer.parseInt(st.nextToken());
graph = new int [n][m];
visited = new boolean[n][m];
// 그래프 초기화
for (int i = 0; i < n; i++) {
st = new StringTokenizer(br.readLine());
for (int j = 0; j < m; j++) {
graph[i][j] = Integer.parseInt(st.nextToken());
}
}
// 가운데 볼록 모양 인덱스 만들기
for (int i = 0; i < 2; i++) {
for (int j = i + 1; j < 3; j++) {
for (int k = j + 1; k < 4; k++) {
sb.append(i).append(j).append(k);
list.add(sb.toString());
sb.delete(0, sb.length());
}
}
}
// 테트로미노 탐색
for (int i = 0; i < graph.length; i++) {
for (int j = 0; j < graph[i].length; j++) {
visited[i][j] = true;
recursion(i, j, 1, 0);
findArrowShape(i,j);
visited[i][j] = false;
}
}
bw.write(max + "\n");
bw.flush();
bw.close();
}
private static void findArrowShape(int r, int c) {
int tmp;
for (String seq : list) {
tmp = graph[r][c];
for (int i = 0; i < seq.length(); i++) {
int idx = seq.charAt(i) - '0';
int nextRow = r + dy[idx];
int nextCol = c + dx[idx];
// 범위를 벗어나면 넘긴다.
if (nextRow < 0 || nextRow >= graph.length
|| nextCol < 0 || nextCol >= graph[0].length) continue;
tmp += graph[nextRow][nextCol];
}
max = Math.max(max, tmp);
}
}
private static void recursion(int r, int c, int depth, int cost) {
if (depth == 4) {
max = Math.max(max, cost + graph[r][c]);
return;
}
for (int i = 0; i < 4; i++) {
int nextRow = r + dy[i];
int nextCol = c + dx[i];
// 범위를 벗어나면 넘기기
if (nextRow < 0 || nextRow >= graph.length
|| nextCol < 0 || nextCol >= graph[0].length) continue;
// 방문 했다면 넘기기
if (visited[nextRow][nextCol]) continue;
visited[nextRow][nextCol] = true;
recursion(nextRow, nextCol, depth + 1, cost + graph[r][c]);
visited[nextRow][nextCol] = false;
}
}
}
❗ 오답노트 / 필요한 지식
- 어렵지 않은 문제인데 저 키보드 방향키 모양때문에 인덱스 조합 이상하게 만들어서 좀 걸렸다.
'baekjoon > Graph_Search' 카테고리의 다른 글
백준 10026번 : 적록색약 자바 (0) | 2024.08.21 |
---|---|
백준 번 2023번 : 신기한 소수 자바 (0) | 2024.08.20 |
백준 2644번 : 촌수계산 자바 (0) | 2024.08.17 |
백준 15686번 : 치킨배달 자바 (0) | 2024.08.13 |
백준 13549번 : 숨바꼭질 3 자바 (0) | 2024.08.08 |