문제 주소 : www.acmicpc.net/problem/19236
19236번: 청소년 상어
첫째 줄부터 4개의 줄에 각 칸의 들어있는 물고기의 정보가 1번 행부터 순서대로 주어진다. 물고기의 정보는 두 정수 ai, bi로 이루어져 있고, ai는 물고기의 번호, bi는 방향을 의미한다. 방향 bi는
www.acmicpc.net
문제 확인
시뮬레이션 문제입니다. dfs방식으로 주어진 방식대로 풀어주면 간단하게 풀 수 있습니다.
주의해야 할 점은 dfs 단계마다 맵 정보를 기록 해 두어야 정확한 답을 구할 수 있습니다.
풀이
방향 전환에 필요한 dx, dy 배열을 선언하고 정해진 물고기의 번호 순서대로 움직여야 하므로 해쉬 기법을 사용합니다.
dfs 단계마다 맵 정보를 기록하기 위해 임시 배열을 선언하고 기록 해 두어 하나의 깊이 탐색이 끝나고 전 단계로 돌아오게 되면 기록 된 정보를 불러와 사용합니다.
모듈러 연산은 많은 시간이 소요되므로 방향의 수가 8 : 2의 배수인 특징을 이용하여 (dir + 1) & 7을 통해 방향전환을 간편하게 할 수 있습니다.
코드
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
|
#include <cstdio>
#include <string.h>
using namespace std;
typedef struct hsh {
short x, y, dir;
}hsh;
short dx[] = { -1, -1, 0, 1, 1, 1, 0, -1 },//상 왼 하 오
dy[] = { 0, -1, -1, -1, 0, 1, 1, 1 };
short map[4][4], mx = -1;
hsh hs[17];
void dfs(short x, short y, short val) {
short cur_dir = hs[map[x][y]].dir, tmp_map[4][4];
hsh tmp_hs[17];
hs[map[x][y]].dir = -1;
val += map[x][y];
map[x][y] = 0;//상어가 현재 위치 물고기를 먹음
for (int i = 1; i < 17; ++i) {
if (hs[i].dir == -1)continue;
short &fx = hs[i].x, &fy = hs[i].y, &fd = hs[i].dir;
while (fx + dx[fd] < 0 || 3 < fx + dx[fd] || fy + dy[fd] < 0 || 3 < fy + dy[fd] ||
(fx + dx[fd] == x && fy + dy[fd] == y))//움직일 수 있는 방향 선택
fd = (fd + 1) & 7;// 6 & 7 = 6, 7 & 7 = 7, 8 & 7 = 0 임을 이용
hs[map[fx + dx[fd]][fy + dy[fd]]] = { fx, fy, hs[map[fx + dx[fd]][fy + dy[fd]]].dir };
map[fx][fy] = map[fx + dx[fd]][fy + dy[fd]];
fx += dx[fd] ,fy += dy[fd];
map[fx][fy] = i;//정보, 맵 수정
}
memcpy(tmp_map, map, sizeof(tmp_map));//정보 기록
memcpy(tmp_hs, hs, sizeof(tmp_hs));
for (x += dx[cur_dir], y += dy[cur_dir]; ; x += dx[cur_dir], y += dy[cur_dir]) {
if(0 <= x && x < 4 && 0 <= y && y < 4){
if (!map[x][y]) {//빈칸인 경우
mx = val > mx ? val : mx;
}
else {
dfs(x, y, val);
memcpy(map, tmp_map, sizeof(tmp_map));//탐색이 끝나면 정보 복구
memcpy(hs, tmp_hs, sizeof(tmp_hs));
}
}
else {//맵 밖의 경우
mx = val > mx ? val : mx;
break;
}
}
}
int main() {
for (short i = 0; i < 4; ++i)
for (short j = 0; j < 4; ++j) {
short dir;
scanf("%hd%hd", &map[i][j],&dir);
hs[map[i][j]] = { i, j, --dir };
}
dfs(0, 0, 0);
printf("%hd", mx);
}
|
cs |
반응형
'알고리즘 문제 > [백준]' 카테고리의 다른 글
[백준] 10868 최솟값 (0) | 2020.12.15 |
---|---|
[백준] 1744 수 묶기 (0) | 2020.12.12 |
[백준] 16637 괄호 추가하기 (0) | 2020.12.05 |
[백준] 14500번: 테트로미노 (0) | 2020.12.05 |
[백준] 16236번: 아기상어 (0) | 2020.12.05 |