본문 바로가기
공부 정리/백준

[백준] 1987 자바 알파벳

by 경적필패. 2022. 1. 31.
반응형

문제

세로 R칸, 가로 C칸으로 된 표 모양의 보드가 있다. 보드의 각 칸에는 대문자 알파벳이 하나씩 적혀 있고, 좌측 상단 칸 (1행 1열) 에는 말이 놓여 있다.

말은 상하좌우로 인접한 네 칸 중의 한 칸으로 이동할 수 있는데, 새로 이동한 칸에 적혀 있는 알파벳은 지금까지 지나온 모든 칸에 적혀 있는 알파벳과는 달라야 한다. 즉, 같은 알파벳이 적힌 칸을 두 번 지날 수 없다.

좌측 상단에서 시작해서, 말이 최대한 몇 칸을 지날 수 있는지를 구하는 프로그램을 작성하시오. 말이 지나는 칸은 좌측 상단의 칸도 포함된다.

입력

첫째 줄에 R과 C가 빈칸을 사이에 두고 주어진다. (1 ≤ R,C ≤ 20) 둘째 줄부터 R개의 줄에 걸쳐서 보드에 적혀 있는 C개의 대문자 알파벳들이 빈칸 없이 주어진다.

출력

첫째 줄에 말이 지날 수 있는 최대의 칸 수를 출력한다.


테스트 케이스

 

입력 1

5 5
IEFCJ
FHFKC
FFALF
HFGCF
HMCHH

출력 1

10

 

입력 2

3 3
AAA
AAA
AAA

출력 2

1

 

입력 3

3 3
ABC
DEF
GHI

출력 3

9


접근

핵심

1. 문자를 맵에 넣기(저는 정수로 바꿔서 했지만, 문자로 해도 상관없을 것 같음)

2. DFS (VISIT배열로 이미 방문한 곳 피해가기)

3. 중복되는 길로 가지 않기 위해 SET사용

 

일반적인 DFS문제에서 SET을 곁들이는 게 제일 중요한 듯싶습니다.

 

------------------------------------------------------------------------------------

 

set을 사용하는 대신, abcde~~를 배열 26개에 나눠서 넣은 다음, 방문을 체크하는 방법도 있었습니다.

set 보다 메모리를 훨씬 절약하고, 시간면에서도 절약 되었습니다.


코드

 

import java.io.*;
import java.math.*;
import java.util.*;

public class Main {
	static int map[][];
	static boolean visit[][];
	static int r,c;
	static int dx[] = {-1,1,0,0};
	static int dy[] = {0,0,-1,1};
	static HashSet<Integer> set = new HashSet<>();
	static int result = 0;
	
	public static void dfs(int x, int y, int cnt) {
		result = Math.max(result, cnt);
		for(int i=0; i<4; i++) {
			int nx = x + dx[i];
			int ny = y + dy[i];
			
			if(nx>=0 && nx<r && ny>=0 && ny<c && !visit[nx][ny] && !set.contains(map[nx][ny])) {
				set.add(map[nx][ny]);
				visit[nx][ny] = true;
				dfs(nx, ny , cnt+1);
				set.remove(map[nx][ny]);
				visit[nx][ny] = false;
			}
		}
		
	}
	public static void main(String[] args) throws NumberFormatException, IOException {
		// TODO Auto-generated method stub
		
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
		
		StringTokenizer st = new StringTokenizer(br.readLine());
		r = Integer.parseInt(st.nextToken());
		c = Integer.parseInt(st.nextToken());
		map = new int[r][c];
		visit = new boolean[r][c];
		for(int i=0; i<r; i++) {
			String s = br.readLine();
			for(int j=0; j<c; j++) {
				map[i][j] = s.charAt(j)-65;
			}
		}
		set.add(map[0][0]);
		visit[0][0] = true;
		dfs(0,0,0);
		bw.write(String.valueOf(++result));
		bw.flush();
		bw.close();
	}
}

주의

저 같은 경우, 첫 시작 지점은 SET, VISIT 값을 설정해주었습니다.

 

반응형

'공부 정리 > 백준' 카테고리의 다른 글

[백준] 자바 1992 쿼드트리  (0) 2022.02.18
[백준] 자바 1914 하노이 탑  (0) 2022.02.07
[백준] 자바 2573 빙산  (0) 2022.01.17
[백준] 자바 1927 최소 힙  (0) 2022.01.04
[백준] 자바 9465 스티커  (0) 2022.01.03

댓글