Skip to content

Commit 5312c2c

Browse files
committed
[Gold III] Title: NxM 보드 완주하기, Time: 432 ms, Memory: 14464 KB -BaekjoonHub
1 parent 047d847 commit 5312c2c

File tree

2 files changed

+142
-0
lines changed

2 files changed

+142
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
import java.io.BufferedReader;
2+
import java.io.IOException;
3+
import java.io.InputStreamReader;
4+
import java.util.ArrayDeque;
5+
import java.util.Arrays;
6+
import java.util.StringTokenizer;
7+
8+
public class Main {
9+
10+
// Test case의 개수가 주어지지 않음!
11+
static int N, M;
12+
static int[] dx = {-1, 0, 1, 0};
13+
static int[] dy = {0, -1, 0, 1};
14+
static char[][] map;
15+
static int ans;
16+
static int wholeCnt;
17+
static boolean[][] visitMap;
18+
19+
public static void main(String[] args) throws IOException {
20+
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
21+
StringTokenizer st;
22+
StringBuilder sb = new StringBuilder();
23+
String input = "";
24+
int tc = 1;
25+
26+
while((input = br.readLine()) != null && !input.isEmpty()){
27+
ans = Integer.MAX_VALUE;
28+
st = new StringTokenizer(input, " ");
29+
N = Integer.parseInt(st.nextToken());
30+
M = Integer.parseInt(st.nextToken());
31+
32+
wholeCnt = 0;
33+
34+
map = new char[N][M];
35+
36+
visitMap = new boolean[N][M];
37+
38+
for(int i = 0; i < N; i++){
39+
String s = br.readLine();
40+
for(int j = 0; j < M; j++){
41+
map[i][j] = s.charAt(j);
42+
if(s.charAt(j) == '.'){
43+
wholeCnt++;
44+
}
45+
}
46+
}
47+
for(int i = 0; i < N; i++){
48+
for(int j = 0; j < M; j++){
49+
for(int k = 0; k < 4; k++){
50+
if(map[i][j] == '.' && isPossible(i + dx[k], j + dy[k])){
51+
findPath(i, j, k, 1, 1);
52+
} else if(map[i][j] == '.' && !isPossible(i + dx[k], j + dy[k])){
53+
findPath(i, j, k, 1, 0);
54+
}
55+
}
56+
}
57+
}
58+
if(ans == Integer.MAX_VALUE)
59+
ans = -1;
60+
System.out.println("Case "+tc++ +": " + ans);
61+
}
62+
System.out.println(sb);
63+
}
64+
65+
public static void findPath(int x, int y, int dir, int cnt, int step){
66+
if(cnt == wholeCnt)
67+
ans = Math.min(ans, step);
68+
visitMap[x][y] = true;
69+
int nx = x + dx[dir];
70+
int ny = y + dy[dir];
71+
72+
// 갈 수 있는 경우
73+
if(isPossible(nx, ny)){
74+
findPath(nx, ny, dir, cnt+1, step);
75+
// 갈 수 없는 경우
76+
} else {
77+
for(int i = 0; i < 4; i++){
78+
if(dir == i)
79+
continue;
80+
nx = x + dx[i];
81+
ny = y + dy[i];
82+
if(isPossible(nx, ny)){
83+
findPath(nx, ny, i, cnt+1, step+1);
84+
}
85+
}
86+
}
87+
visitMap[x][y] = false;
88+
}
89+
90+
public static boolean isPossible(int x, int y){
91+
return !(x < 0 || y < 0 || x >= N || y >= M || visitMap[x][y] || map[x][y] == '*');
92+
}
93+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# [Gold III] NxM 보드 완주하기 - 9944
2+
3+
[문제 링크](https://www.acmicpc.net/problem/9944)
4+
5+
### 성능 요약
6+
7+
메모리: 14464 KB, 시간: 432 ms
8+
9+
### 분류
10+
11+
백트래킹, 구현
12+
13+
### 제출 일자
14+
15+
2024년 7월 8일 17:43:53
16+
17+
### 문제 설명
18+
19+
<p dir="ltr">N×M 보드 위에서 할 수 있는 게임이 있다. 보드는 크기가 1×1인 정사각형 칸으로 나누어져 있다. 보드의 각 칸은 빈 칸 또는 장애물이다. 장애물은 아래 그림에선 어두운 사각형으로 표시되어져 있다.</p>
20+
21+
<p dir="ltr">게임을 시작하려면 보드의 빈 칸 위에 공을 하나 놓아야 한다. 아래 그림에서 공은 회색 점으로 표시되어져 있다. 게임은 단계로 이루어져 있고, 각 단계는 아래와 같이 구성되어져 있다.</p>
22+
23+
<ul dir="ltr">
24+
<li>위, 아래, 오른쪽, 왼쪽 중 방향 하나를 고른 다음, 그 방향으로 공을 계속해서 이동시킨다.</li>
25+
<li>공은 장애물, 보드의 경계, 이미 공이 지나갔던 칸을 만나기 전까지 계속해서 이동한다.</li>
26+
</ul>
27+
28+
<p>게임은 공이 더 이상 이동할 수 없을 때 끝난다. 이 때, 모든 빈 칸을 공이 방문한 적이 있어야 한다.</p>
29+
30+
<p>아래 그림은 총 10단계 만에 모든 칸을 방문하는 방법이다.</p>
31+
32+
<p style="text-align: center;"><img alt="" src="https://www.acmicpc.net/upload/images2/fboard.png" style="height: 150px; width: 167px;"></p>
33+
34+
<p>보드의 상태가 주어졌을 때, 모든 칸을 방문하기 위한 이동 횟수의 최솟값을 구하는 프로그램을 작성하시오.</p>
35+
36+
### 입력
37+
38+
<p>입력은 여러 개의 테스트 케이스로 이루어져 있다.</p>
39+
40+
<p>각 테스트 케이스의 첫째 줄에는 보드의 크기를 나타내는 N과 M이 주어진다. N은 세로 크기, M은 가로 크기이고, 두 값은 30보다 작거나 같은 자연수이다. 둘째 줄부터 N개의 줄에는 보드의 상태가 주어진다. 보드의 상태는 장애물을 나타내는 '*'과 빈 칸을 나타내는 '.'으로 이루어져 있다.</p>
41+
42+
<p>입력으로 주어진 보드가 장애물로만 이루어진 경우는 없다.</p>
43+
44+
### 출력
45+
46+
<p dir="ltr">각 테스트 케이스마다 보드의 모든 빈 칸을 방문하는 최소 이동 횟수를 출력한다. 출력 형식은 예제를 참고한다.</p>
47+
48+
<p dir="ltr">만약, 모든 빈 칸을 방문할 수 없다면 최소 이동 횟수는 -1이다. 가능한 이동 경로의 수는 1,000,000개를 넘지 않는다.</p>
49+

0 commit comments

Comments
 (0)