알고리즘/백준
[백준] 1987번 : 알파벳 - 자바(JAVA)
Junuuu
2022. 4. 2. 00:01
반응형
https://www.acmicpc.net/problem/1987
1987번: 알파벳
세로 R칸, 가로 C칸으로 된 표 모양의 보드가 있다. 보드의 각 칸에는 대문자 알파벳이 하나씩 적혀 있고, 좌측 상단 칸 (1행 1열) 에는 말이 놓여 있다. 말은 상하좌우로 인접한 네 칸 중의 한 칸으
www.acmicpc.net
문제 해석
세로 R 칸 가로 C칸으로 된 표 모양의 보드가 존재합니다.
보드의 각 칸에는 알파벳이 하나씩 적혀있고 좌측 상단 칸(0,0)에는 말이 놓여 있습니다.
말은 상하좌우 인접한 네 칸 중의 한 칸으로 이동할 수 있습니다.
새로 이동한 칸에 적혀 있는 알파벳은 지금까지 지나온 모든 칸에 적혀 있는 알파벳과는 달라야 합니다.
최초에 말이 지나는 칸은 좌측 상단의 칸도 포함됩니다.
말이 최대한 몇 칸을 지날 수 있는지 구하는 프로그램을 작성하세요.
문제 풀이 전 설계
중복을 제거해주는 HashMap을 사용하면 좋을 것 같습니다.
BFS를 하면서 한칸씩 앞으로 나아가게 될 때 어떻게 중복 제거를 할 것인가?
BFS는 힘들 것 같다는 생각이 들었습니다.
DFS를 사용한다면 괜찮을 것 같습니다 DFS를 통해 완전 탐색을 해야 합니다.
최대 칸 수를 구해야 하기 때문에 백 트레킹도 힘들 것 같습니다.
코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashSet;
import java.util.Set;
import java.util.StringTokenizer;
class Hourse {
int y;
int x;
int moveCount;
public Hourse(int y, int x) {
super();
this.y = y;
this.x = x;
moveCount = 1;
}
@Override
public String toString() {
return "Hourse [y=" + y + ", x=" + x + ", moveCount=" + moveCount + "]";
}
}
public class Main_1987_알파벳 {
static char[][] board;
static int[] dy = { -1, 1, 0, 0 };
static int[] dx = { 0, 0, -1, 1 };
static final int Direction = 4;
static int R, C;
static int moveDistance = Integer.MIN_VALUE;
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine(), " ");
R = Integer.parseInt(st.nextToken());
C = Integer.parseInt(st.nextToken());
board = new char[R][C];
for (int y = 0; y < R; y++) {
String tempRow = br.readLine();
for (int x = 0; x < C; x++) {
board[y][x] = tempRow.charAt(x);
}
}
Set<Character> hashSet = new HashSet<Character>();
Hourse hourse = new Hourse(0, 0);
// 현재 말의 위치는 0,0 moveCount = 1으로 설정해서 처음에도 움직이는 취급
hashSet.add(board[0][0]);
DFS(hourse, hashSet);
System.out.println(moveDistance);
}
private static void DFS(Hourse hourse, Set<Character> hashSet) {
for (int k = 0; k < Direction; k++) {
int originY = hourse.y;
int originX = hourse.x;
int tempY = hourse.y + dy[k];
int tempX = hourse.x + dx[k];
if (!isPosValid(tempY, tempX)) {
continue;
}
char alphabet = board[tempY][tempX];
if (isDuplicated(alphabet, hashSet)) {
moveDistance = hourse.moveCount > moveDistance ? hourse.moveCount : moveDistance;
continue;
}
hourse.x = tempX;
hourse.y = tempY;
hourse.moveCount++;
hashSet.add(alphabet);
DFS(hourse, hashSet);
hourse.x = originX;
hourse.y = originY;
hourse.moveCount--;
hashSet.remove(alphabet);
}
}
private static boolean isPosValid(int tempY, int tempX) {
return (tempY >= 0 && tempX >= 0 && tempY < R && tempX < C);
}
private static boolean isDuplicated(char alphabet, Set<Character> hashSet) {
return hashSet.contains(alphabet);
}
}