일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 다리 만들기2
- 부분수열의 합
- 좋아요
- 댓글
- 인스타
- 16637
- 14502
- 재귀
- 장고
- 미세먼지 안녕!
- 17143
- 색종이 붙이기
- 17136
- 연산자 끼워넣기
- 괄호추가하기
- 17144
- 14888
- 17472
- 6603
- Java
- 로또
- 인스타그램
- 9095
- Ajax
- 따라하기
- 백준
- 알고리즘
- 구슬탈출2
- django
- 1182
- Today
- Total
Be a developer
백준 14502 연구소 본문
왜 상반기 기출문제를 풀 때 안풀어 보았는지는 모르겠지만, 기출 문제를 다시 한 번 풀어보는 과정에서 풀게 되었다.
안전한 곳의 수를 세면 되기 때문에, map을 입력 받을 때 그 수를 세어주었다. (2차원 배열을 다 돌면서 세지 않고 이렇게 하는 방법을 다른 문제에서 다뤄본 적이 있었다.)
일단 바이러스는 퍼져나가는 것이기 때문에 BFS로 풀어야 했고, 벽의 위치는 안전한 곳에서 3개를 고르는 조합이었기 때문에 DFS를 통해서 해결했다.
다만, DFS(재귀)를 돌면서 BFS를 돌아야 했기 때문에 시간 복잡도를 계산해보아야 했고, 충분하다는 생각이 들었다.(시뮬레이션 하는 것 말고는 다른 방법이 생각나지 않았다.)
Queue를 만들어 바이러스의 위치를 넣어주고, visit를 통해서 BFS를 돌렸다.
다만 BFS를 돌 때마다 인자로 전달하는 Queue와 visit 배열이 변경되기 때문에 BFS에 전달하기 전에 Queue와 visit를 복사한 후 전달해주어야 뒤 연산에 영향을 주지 않는다.
DFS에서 종료 조건과 답을 구해야 하는 조건문의 순서는 정말 중요하다. 이번에도 이 순서가 바껴서 2번이나 실패를 한 후에 테스트 케이스를 여러 개 만들어서 돌려보다가 찾게 되었다.
또한 답이 너무 늦게 나와서 왜 그런가 했는데, 답을 구하는 조건문에서 return을 해주지 않아서 였다.
2가지 모두 항상 하는 실수 인데 꼭 다시 실수하게 되는 것 같다.
DFS에 아직 약한 것 같다. 재귀로 문제를 풀 때 좀 더 신중하게 풀어야 겠다.
아래는 코드이다.
BFS를 돌 때 안전 영역의 수가 이미 ans에 저장되어 있는 값보다 더 작아지면 더이상 BFS를 돌지 않고 return하면 좀 더 최적화를 시킬 수 있을 것 같다.
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
|
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;
public class Main {
static int ans, n, m, size;
static int[] dr = { -1, 0, 1, 0 };
static int[] dc = { 0, 1, 0, -1 };
static int[] rows;
static int[] cols;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
n = Integer.parseInt(st.nextToken());
m = Integer.parseInt(st.nextToken());
int[][] arr = new int[n][m];// 연구소
int safe = 0;// 안전한 곳
Queue<Integer> virus = new LinkedList<Integer>();
int[][] visit = new int[n][m];// 방문지 체크
rows = new int[64];// 안전한 곳 좌표
cols = new int[64];
ans = 0;
for (int i = 0; i < n; i++) {
st = new StringTokenizer(br.readLine());
for (int j = 0; j < m; j++) {
arr[i][j] = Integer.parseInt(st.nextToken());
if (arr[i][j] == 0) {// 안전한 곳 저장
rows[safe] = i;
cols[safe++] = j;
}
if (arr[i][j] == 2) {// 바이러스 있는 곳 큐에 저장
virus.offer(i);
virus.offer(j);
visit[i][j] = 2;
}
if (arr[i][j] == 1)// 벽있는 곳 visit
visit[i][j] = 1;
}
}
size = safe;
perm(visit, virus, safe, 0, 0);
System.out.println(ans);
}
static void perm(int[][] visit, Queue<Integer> virus, int safe, int cnt, int idx) {
if (cnt == 3) {
Queue<Integer> cpVirus = new LinkedList<>();
for (int i = 0; i < virus.size(); i++)
cpVirus.addAll(virus);
int[][] cpVisit = new int[n][m];
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
cpVisit[i][j] = visit[i][j];
}
}
bfs(cpVirus, cpVisit, safe);
return;
}
if (size <= idx)
return;
int row = rows[idx];
int col = cols[idx];
visit[row][col] = 1;
perm(visit, virus, safe - 1, cnt + 1, idx + 1);
visit[row][col] = 0;
perm(visit, virus, safe, cnt, idx + 1);
}
private static void bfs(Queue<Integer> cpVirus, int[][] cpVisit, int safe) {
while (!cpVirus.isEmpty()) {
int row = cpVirus.poll();
int col = cpVirus.poll();
for (int i = 0; i < 4; i++) {
int nr = row + dr[i];
int nc = col + dc[i];
if (nr < 0 || nr >= n || nc < 0 || nc >= m || cpVisit[nr][nc] != 0)
continue;
cpVisit[nr][nc] = 2;
cpVirus.offer(nr);
cpVirus.offer(nc);
safe--;
}
}
ans = (ans < safe) ? safe : ans;
}
}
|
cs |
'sw 역량테스트' 카테고리의 다른 글
백준 17144 미세먼지 안녕! (0) | 2019.09.04 |
---|---|
백준 17143 낚시왕 (0) | 2019.09.04 |
백준 12100 2048 (0) | 2019.08.15 |
백준 13460 구슬 탈출2 (2) | 2019.08.13 |
백준 3190 뱀 (0) | 2019.04.24 |