반응형
https://www.acmicpc.net/problem/5427
5427번: 불
상근이는 빈 공간과 벽으로 이루어진 건물에 갇혀있다. 건물의 일부에는 불이 났고, 상근이는 출구를 향해 뛰고 있다. 매 초마다, 불은 동서남북 방향으로 인접한 빈 공간으로 퍼져나간다. 벽에
www.acmicpc.net
문제
상근이는 빈 공간과 벽으로 이루어진 건물에 갇혀있다. 건물의 일부에는 불이 났고, 상근이는 출구를 향해 뛰고 있다.
매 초마다, 불은 동서남북 방향으로 인접한 빈 공간으로 퍼져나간다. 벽에는 불이 붙지 않는다. 상근이는 동서남북 인접한 칸으로 이동할 수 있으며, 1초가 걸린다. 상근이는 벽을 통과할 수 없고, 불이 옮겨진 칸 또는 이제 불이 붙으려는 칸으로 이동할 수 없다. 상근이가 있는 칸에 불이 옮겨옴과 동시에 다른 칸으로 이동할 수 있다.
빌딩의 지도가 주어졌을 때, 얼마나 빨리 빌딩을 탈출할 수 있는지 구하는 프로그램을 작성하시오.
입력
첫째 줄에 테스트 케이스의 개수가 주어진다. 테스트 케이스는 최대 100개이다.
각 테스트 케이스의 첫째 줄에는 빌딩 지도의 너비와 높이 w와 h가 주어진다. (1 ≤ w,h ≤ 1000)
다음 h개 줄에는 w개의 문자, 빌딩의 지도가 주어진다.
- '.': 빈 공간
- '#': 벽
- '@': 상근이의 시작 위치
- '*': 불
각 지도에 @의 개수는 하나이다.
출력
각 테스트 케이스마다 빌딩을 탈출하는데 가장 빠른 시간을 출력한다. 빌딩을 탈출할 수 없는 경우에는 "IMPOSSIBLE"을 출력한다.
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
|
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
public class Main
{
static char[][] MAP;
static char[][] fMAP;
static boolean[][] sVisited;
static boolean[][] fVisited;
static int T, w, h;
static Queue<POINT> fq;
static Queue<POINT> sq;
static int[] dx = { -1, 1, 0, 0 };
static int[] dy = { 0, 0, -1, 1 };
static int cnt;
static boolean check;
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
fq = new LinkedList<POINT>();
sq = new LinkedList<POINT>();
T = sc.nextInt();
for (int test_case = 1; test_case <= T; test_case++)
{
w = sc.nextInt();
h = sc.nextInt();
fq.clear();
sq.clear();
cnt = 0;
check = false;
MAP = new char[h][w];
sVisited = new boolean[h][w];
fVisited = new boolean[h][w];
sc.nextLine();
for (int i = 0; i < h; i++) {
String str = sc.nextLine();
for (int j = 0; j < w; j++) {
MAP[i][j] = str.charAt(j);
sVisited[i][j] = false;
fVisited[i][j] = false;
}
}
for (int i = 0; i < h; i++) {
for (int j = 0; j < w; j++) {
if (MAP[i][j] == '*') {
fq.offer(new POINT(i, j));
fVisited[i][j] = true;
}
if (MAP[i][j] == '@') {
sq.offer(new POINT(i, j));
sVisited[i][j] = true;
}
}
}
cnt=0;
check = false;
move();
if(check)
System.out.println(cnt);
else
System.out.println("IMPOSSIBLE");
}
}
private static void move()
{
for (int i = 0; i < h; i++)
{
for (int j = 0; j < w; j++)
{
if (MAP[i][j] == '*')
{
fq.offer(new POINT(i, j));
fVisited[i][j] = true;
}
if (MAP[i][j] == '@')
{
sq.offer(new POINT(i, j));
sVisited[i][j] = true;
}
}
}
while (!sq.isEmpty())
{
int fqSize = fq.size();
int sqSize = sq.size();
// 불 이동
for (int a = 0; a < fqSize; a++)
{
POINT fp = fq.poll();
for (int i = 0; i < 4; i++)
{
int nextFx = fp.x + dx[i];
int nextFy = fp.y + dy[i];
if (nextFx < 0 || nextFx >= h || nextFy < 0 || nextFy >= w)
{
check = false;
continue;
}
if (MAP[nextFx][nextFy] == '#' || fVisited[nextFx][nextFy])
{
continue;
}
fq.offer(new POINT(nextFx, nextFy));
MAP[nextFx][nextFy] = '*';
fVisited[nextFx][nextFy] = true;
}
}
// 상근이 이동
cnt++;
for (int b = 0; b < sqSize; b++)
{
POINT sp = sq.poll();
sVisited[sp.x][sp.y] = true;
for (int i = 0; i < 4; i++)
{
int nextSx = sp.x + dx[i];
int nextSy = sp.y + dy[i];
if (nextSx < 0 || nextSx >= h || nextSy < 0 || nextSy >= w)
{
check = true;
return;
}
if (MAP[nextSx][nextSy] != '.' || sVisited[nextSx][nextSy])
continue;
sq.offer(new POINT(nextSx, nextSy));
sVisited[nextSx][nextSy] = true;
}
}
}
}
}
class POINT
{
int x, y;
POINT(int x, int y)
{
this.x = x;
this.y = y;
}
}
|
cs |
반응형
'Algorithm > Baekjoon Online Judge' 카테고리의 다른 글
[2468] 안전영역 (0) | 2019.02.15 |
---|---|
[2573] 빙산 (0) | 2019.01.02 |
[5014] 스타트링크 (0) | 2018.12.20 |
[7569] 토마토 (0) | 2018.12.16 |
[11559] Puyo Puyo (0) | 2018.12.06 |