문제
‘쩰리’는 점프하는 것을 좋아하는 젤리다. 단순히 점프하는 것에 지루함을 느낀 ‘쩰리’는 새로운 점프 게임을 해보고 싶어 한다. 새로운 점프 게임의 조건은 다음과 같다.
- ‘쩰리’는 가로와 세로의 칸 수가 같은 정사각형의 구역 내부에서만 움직일 수 있다. ‘쩰리’가 정사각형 구역의 외부로 나가는 경우엔 바닥으로 떨어져 즉시 게임에서 패배하게 된다.
- ‘쩰리’의 출발점은 항상 정사각형의 가장 왼쪽, 가장 위의 칸이다. 다른 출발점에서는 출발하지 않는다.
- ‘쩰리’가 이동 가능한 방향은 오른쪽과 아래뿐이다. 위쪽과 왼쪽으로는 이동할 수 없다.
- ‘쩰리’가 가장 오른쪽, 가장 아래 칸에 도달하는 순간, 그 즉시 ‘쩰리’의 승리로 게임은 종료된다.
- ‘쩰리’가 한 번에 이동할 수 있는 칸의 수는, 현재 밟고 있는 칸에 쓰여 있는 수만큼이다. 칸에 쓰여 있는 수 초과나 그 미만으로 이동할 수 없다.
새로운 게임이 맘에 든 ‘쩰리’는, 계속 게임을 진행해 마침내 최종 단계에 도달했다. 하지만, 게임을 진행하는 구역이 너무 넓어져버린 나머지, 이 게임에서 이길 수 있는지 없는지 가늠할 수 없어졌다. ‘쩰리’는 유능한 프로그래머인 당신에게 주어진 구역에서 승리할 수 있는지 알아봐 달라고 부탁했다. ‘쩰리’를 도와 주어진 게임 구역에서 끝 점(오른쪽 맨 아래 칸)까지 도달할 수 있는지를 알아보자!
입력
입력의 첫 번째 줄에는 게임 구역의 크기 N (2 ≤ N ≤ 3)이 주어진다.
입력의 두 번째 줄부터 마지막 줄까지 게임판의 구역(맵)이 주어진다.
게임판의 승리 지점(오른쪽 맨 아래 칸)에는 -1이 쓰여있고, 나머지 칸에는 0 이상 100 이하의 정수가 쓰여있다.
출력
‘쩰리’가 끝 점에 도달할 수 있으면 “HaruHaru”(인용부호 없이), 도달할 수 없으면 “Hing” (인용부호 없이)을 한 줄에 출력합니다.
문제 설명
점프왕 쩰리 문제는 정사각형 보드판 위에 쩰리가 첫 위치 (0,0)에서 끝 위치(N - 1, N -1)로 이동 가능하는지 판단 하는 문제이다.
이동할 수 있는 칸은 쩰리가 밟고 있는 칸에 쓰여있고, 이동 가능한 방향은 오른쪽과 아래만 가능하다.
중요한건 이동할 수 있는 칸이 3이라면 3칸을 이동해야 한다. 1칸 2칸은 이동하면 안 된다.
해설
점프왕 쩰리 문제는 이동 가능한 구역을 오른쪽 아래 하나하나 탐색하면서 끝 위치에 도달할 수 있는지 파악하면 된다.
- 완전 탐색으로 하면 안 된다.
- 현재 밟고 있는 칸에 적혀있는 이동 가능 칸을 이용하여 BFS 혹은 DFS 탐색을 사용
- 끝 위치에 도달하면 "HaruHaru"를 도달할 수 없으면 "Hing"을 출력하자
나는 DFS를 사용하여 풀었지만 BFS 탐색을 해도 상관없다.
DFS 탐색을 Stack, 재귀를 이용해 두 가지 방식으로 풀었다.
1. Stack을 이용한 DFS 코드
import java.io.*;
import java.util.*;
public class Main {
static int N;
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
N = Integer.parseInt(br.readLine());
int[][] board = new int[N][N];
for (int i = 0; i < N; i++) {
StringTokenizer st = new StringTokenizer(br.readLine(), " ");
for (int j = 0; j < N; j++) {
board[i][j] = Integer.parseInt(st.nextToken());
}
}
System.out.println(dfs(board));
br.close();
}
static public String dfs(int[][] board) {
Stack<Node> stack = new Stack<>();
boolean[][] visited = new boolean[N][N];
stack.add(new Node(0, 0, board[0][0]));
while(!stack.isEmpty()) {
Node cur = stack.pop();
int x = cur.x;
int y = cur.y;
int count = cur.count;
if (board[x][y] == -1) {
return "HaruHaru";
}
if (visited[x][y]) {
continue;
}
visited[x][y] = true;
if (x + count < N && !visited[x + count][y]) {
stack.add(new Node(x + count, y, board[x + count][y]));
}
if (y + count < N && !visited[x][y + count]) {
stack.add(new Node(x, y + count, board[x][y + count]));
}
}
return "Hing";
}
}
class Node {
int x;
int y;
int count;
public Node(int x, int y, int count) {
this.x = x;
this.y = y;
this.count = count;
}
}
2. 재귀함수를 이용한 코드
import java.io.*;
import java.util.*;
public class Main {
static int N;
static int[][] board;
static boolean[][] visited;
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
N = Integer.parseInt(br.readLine());
board = new int[N][N];
visited = new boolean[N][N];
for (int i = 0; i < N; i++) {
StringTokenizer st = new StringTokenizer(br.readLine(), " ");
for (int j = 0; j < N; j++) {
board[i][j] = Integer.parseInt(st.nextToken());
}
}
System.out.println(dfs(0, 0));
br.close();
}
static public String dfs(int x, int y) {
int count = board[x][y];
visited[x][y] = true;
if (count == -1) {
return "HaruHaru";
}
if (x + count < N && !visited[x + count][y] && !dfs(x + count, y).equals("Hing")) {
return "HaruHaru";
}
if (y + count < N && !visited[x][y + count] && !dfs(x, y + count).equals("Hing")) {
return "HaruHaru";
}
return "Hing";
}
}
'알고리즘 > BFS, DFS' 카테고리의 다른 글
[프로그래머스] 네트워크 Lv3 JAVA [탐색][엄탱] (4) | 2023.07.09 |
---|---|
[프로그래머스] 타겟 넘버 Lv2 JAVA [DFS][엄탱] (7) | 2023.07.09 |
[백준] 14502번 연구소 java[브루트포스, 탐색][엄탱] (2) | 2023.03.22 |
[자바]백준 정수 a를 k로 만들기 [탐색] [엄탱] (4) | 2023.03.12 |
[자바]백준 1316번 그룹 단어 체커 [그래프 탐색][엄탱] (4) | 2023.03.02 |