코딩테스트/SWExpert
[코딩테스트] SWEA 2819 격자판의 숫자 이어 붙이기(Java)
[dev] hiro
2025. 6. 26. 23:27
제가 공부한 내용을 정리하는 블로그입니다.
아직 많이 부족하고 배울게 너무나도 많습니다. 틀린내용이 있으면 언제나 가감없이 말씀해주시면 감사하겠습니다😁
SWEA 2819 격자판의 숫자 이어붙이기입니다.
포인트
제가 생각한 포인트는 다음과 같습니다.
- 4X4의 격자
- 시작점이 16개
- 완전탐색 가능성
- 총 7개의 길이.
- 16 * 4^6 = 2^16의 작업
- Java기준 4초 내 가능 => 완전탐색 가능
- DFS(재귀)를 통한 탐색
- 각 칸을 시작점으로 재귀적으로 탐색하여 경로를 구성.
- 각 숫자는 중복을 허용하지 않는 점. => HashSet 사용
소스코드
package SWExpert.Implementation;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashSet;
import java.util.Set;
import java.util.StringTokenizer;
public class Q2819 {
private static int tc;
private static int[][] nums;
private static Set<String> s;
private static int[] dx = {-1, 0, 1, 0};
private static int[] dy = {0, 1, 0, -1};
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
tc = Integer.parseInt(br.readLine());
StringBuilder sb = new StringBuilder();
StringTokenizer st;
nums = new int[4][4];
for (int t = 1; t <= tc; t++) {
sb.append("#").append(t).append(" ");
s = new HashSet<>();
for (int i = 0; i < 4; i++) {
st = new StringTokenizer(br.readLine());
for (int j = 0; j < 4; j++) {
nums[i][j] = Integer.parseInt(st.nextToken());
}
}
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
findNums(0, i, j, "" + nums[i][j]);
}
}
sb.append(s.size()).append("\n");
}
System.out.println(sb);
}
public static void findNums(int depth, int x, int y, String num) {
if (depth == 6) {
s.add(num);
return;
}
for (int idx = 0; idx < 4; idx++) {
int nx = x + dx[idx];
int ny = y + dy[idx];
if (inRange(nx, ny)) {
findNums(depth + 1, nx, ny, num + nums[nx][ny]);
}
}
}
private static boolean inRange(int x, int y) {
return 0 <= x && x < 4 && 0 <= y && y < 4;
}
}
/*
1
1 1 1 1
1 1 1 2
1 1 2 1
1 1 1 1
*/
코드 설명
- main 함수
- BufferedReader와 StringTokenizer를 사용해 빠르게 입력을 처리합니다.
- 4×4 격자를 2차원 배열 nums에 저장합니다.
- 격자의 모든 칸을 시작점으로 삼아, (i, j) 위치에서부터 DFS 재귀 함수 findNums를 호출합니다.
- inRange(int x, int y)
- 좌표 (x, y)가 격자 범위(0 이상 4 미만) 내에 있는지 확인하는 함수입니다.
- 상하좌우로 이동할 때 격자를 벗어나지 않도록 범위 체크에 사용됩니다.
- findNums(int depth, int x, int y, String num)
재귀 함수, (x, y)를 기준으로 num 선언
- DFS 방식의 재귀 함수입니다.
- 현재 좌표 (x, y)에서 시작해 문자열 num을 이어 붙이며 탐색합니다.
- depth == 6이 되면 총 7자리 수가 완성된 것이므로 HashSet에 저장합니다.
- 상하좌우로 이동하기 위해 dx, dy 배열을 사용하여 다음 위치 (nextX, nextY)를 구하고, 범위 내에 있다면 재귀적으로 계속 탐색합니다.