View
https://www.acmicpc.net/problem/2210
문제 요약
5×5 크기의 숫자판이 있다. 각각의 칸에는 숫자(digit, 0부터 9까지)가 적혀 있다. 이 숫자판의 임의의 위치에서 시작해서, 인접해 있는 네 방향으로 다섯 번 이동하면서, 각 칸에 적혀있는 숫자를 차례로 붙이면 6자리의 수가 된다. 이동을 할 때에는 한 번 거쳤던 칸을 다시 거쳐도 되며, 0으로 시작하는 000123과 같은 수로 만들 수 있다.
숫자판이 주어졌을 때, 만들 수 있는 서로 다른 여섯 자리의 수들의 개수를 구하는 프로그램을 작성하시오.
문제 해결 아이디어
입력으로 받은 2차원 배열을 네 방향으로 dfs 탐색해 준다. 탐색하면서 만들어지고 있는 문자열을 매개변수로 가지고 탐색을 하며, 6자리를 다 만들었을 때 만들어진 문자열을 최종 HashSet에 add한다. HashSet을 자료형으로 선택한 이유는 중복이 걸러지기 때문이다.
완성된 코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashSet;
import java.util.StringTokenizer;
public class Main_BOJ_2210_숫자판점프 {
/*
* 132ms
*/
static String[][] input;
static HashSet<String> set;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = null;
input = new String[5][5];
for (int i = 0; i < 5; i++) {
st = new StringTokenizer(br.readLine(), " ");
for (int j = 0; j < 5; j++) {
input[i][j] = st.nextToken();
}
}
set = new HashSet<String>();
for (int i = 0; i < 5; i++)
for (int j = 0; j < 5; j++)
dfs(i, j, "");
System.out.println(set.size());
}
public static void dfs(int i, int j, String res) {
if (res.length() == 6) {
set.add(res);
return;
}
int[] dr = { -1, 1, 0, 0 };
int[] dc = { 0, 0, -1, 1 };
for (int p = 0; p < 4; p++) {
int nr = i + dr[p];
int nc = j + dc[p];
if (nr >= 0 && nr < 5 && nc >= 0 && nc < 5)
dfs(nr, nc, res + input[nr][nc]);
}
}
}
'Level-Up > 알고리즘' 카테고리의 다른 글
[백준] 1347. 미로 만들기 - 실버4 (0) | 2021.09.28 |
---|---|
[백준] 7576. 토마토 - 실버1 (0) | 2021.09.28 |
[백준] 4963. 섬의 개수 - 실버2 (0) | 2021.09.28 |
[백준] 2784. 가로 세로 퍼즐 - 실버3 (0) | 2021.09.28 |
[백준] 7490. 0 만들기 - 골드5 (0) | 2021.09.01 |
reply