| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | ||||||
| 2 | 3 | 4 | 5 | 6 | 7 | 8 |
| 9 | 10 | 11 | 12 | 13 | 14 | 15 |
| 16 | 17 | 18 | 19 | 20 | 21 | 22 |
| 23 | 24 | 25 | 26 | 27 | 28 | 29 |
| 30 |
- Redis
- UNICON2023
- 프리티어
- UNICON
- CICD
- bastion host
- 백엔드개발자
- 스프링부트
- Spring boot
- 게임개발동아리
- 인프라
- 프롬프트엔지니어링
- 체크인미팅
- 생활코딩
- 티스토리챌린지
- Route53
- EC2
- openAI API
- 전국대학생게임개발동아리연합회
- 42서울
- 프로그래밍
- spring ai
- 라피신
- 도커
- 캡스톤디자인프로젝트
- 오블완
- AWS
- 개발공부
- UNIDEV
- NAT gateway
- Today
- Total
Hyun's Wonderwall
[백준 골드2] 1103번: 게임 (DP, DFS) - Java 본문
1103번: 게임
https://www.acmicpc.net/problem/1103
문제
형택이는 1부터 9까지의 숫자와, 구멍이 있는 직사각형 보드에서 재밌는 게임을 한다.
일단 보드의 가장 왼쪽 위에 동전을 하나 올려놓는다. 그다음에 다음과 같이 동전을 움직인다.
동전이 있는 곳에 쓰여 있는 숫자 X를 본다.
위, 아래, 왼쪽, 오른쪽 방향 중에 한가지를 고른다.
동전을 위에서 고른 방향으로 X만큼 움직인다. 이때, 중간에 있는 구멍은 무시한다.
만약 동전이 구멍에 빠지거나, 보드의 바깥으로 나간다면 게임은 종료된다. 형택이는 이 재밌는 게임을 되도록이면 오래 하고 싶다.
보드의 상태가 주어졌을 때, 형택이가 최대 몇 번 동전을 움직일 수 있는지 구하는 프로그램을 작성하시오.
입력
줄에 보드의 세로 크기 N과 가로 크기 M이 주어진다. 이 값은 모두 50보다 작거나 같은 자연수이다. 둘째 줄부터 N개의 줄에 보드의 상태가 주어진다. 쓰여 있는 숫자는 1부터 9까지의 자연수 또는 H이다. 가장 왼쪽 위칸은 H가 아니다. H는 구멍이다.
출력
첫째 줄에 문제의 정답을 출력한다. 만약 형택이가 동전을 무한번 움직일 수 있다면 -1을 출력한다.
예제 입력 1
3 7
3942178
1234567
9123532
예제 출력 1
5
예제 입력 2
1 10
2H3HH4HHH5
예제 출력 2
4
예제 입력 3
4 4
3994
9999
9999
2924
예제 출력 3
-1
예제 입력 4
4 6
123456
234567
345678
456789
예제 출력 4
4
예제 입력 5
1 1
9
예제 출력 5
1
예제 입력 6
3 7
2H9HH11
HHHHH11
9HHHH11
예제 출력 6
2
알고리즘: 다이나믹 프로그래밍, 그래프 이론, 그래프 탐색, 깊이 우선 탐색
풀이
dfs+visited 사용해서 풀었는데 시간초과이 문제에서 왜 DP가 필요한지 처음엔 잘 감이 안 왔는데 뒤에서부터 생각하니 이해하게 됐다
이동횟수가 어떻게보면 최대 깊이인데
DP로 이전에 해당 좌표 방문했을때 도달했던 최대 깊이를 저장해두고 활용해야 시간초과가 안 났다
(추후 설명 보충)
import java.io.*;
import java.util.*;
public class Main {
static int n, m;
static int[][] board;
static int[][] dp;
static boolean[][] visited;
static boolean isInfinite;
public static int dfs(int x, int y) {
if (x < 0 || x >= n || y < 0 || y >= m || board[x][y] == 0) {
return 0;
}
// 현재 경로에 이미 방문했다면 사이클
if (visited[x][y]) {
isInfinite = true;
return 0;
}
// 이미 dp에 계산한 값이 있는 경우 바로 리턴
if (dp[x][y] != -1) {
return dp[x][y];
}
visited[x][y] = true;
int num = board[x][y];
int maxDepth = 0;
maxDepth = Math.max(maxDepth, dfs(x + num, y));
maxDepth = Math.max(maxDepth, dfs(x - num, y));
maxDepth = Math.max(maxDepth, dfs(x, y + num));
maxDepth = Math.max(maxDepth, dfs(x, y - num));
dp[x][y] = maxDepth + 1;
visited[x][y] = false;
return dp[x][y];
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] nm = br.readLine().split(" ");
n = Integer.parseInt(nm[0]);
m = Integer.parseInt(nm[1]);
board = new int[n][m];
dp = new int[n][m];
visited = new boolean[n][m];
for (int i = 0; i < n; i++) {
String line = br.readLine();
for (int j = 0; j < m; j++) {
char c = line.charAt(j);
if (c == 'H') c = '0';
board[i][j] = Character.getNumericValue(c);
dp[i][j] = -1;
}
}
int ans = dfs(0, 0);
if (isInfinite)
System.out.println(-1);
else
System.out.println(ans);
}
}
'Study > PS' 카테고리의 다른 글
| [백준 골드4] 2240번: 자두나무 (DP) - Java (2) | 2025.08.17 |
|---|---|
| [백준 실버3] 14501번: 퇴사 (DP) - Java (3) | 2025.08.17 |
| [백준 골드2] 1781번: 컵라면 (우선순위 큐, 그리디) - Java (3) | 2025.08.06 |
| [백준 골드1] 1450번: 냅색문제 (이분탐색, 중간에서 만나기) - Java (4) | 2025.08.06 |
| [백준 골드1] 16118번: 달빛 여우 (다익스트라) - Java (4) | 2025.08.04 |