알고리즘 문제/[백준]

[백준] 19236 청소년 상어

latter2005 2020. 12. 9. 16:53

문제 주소 : 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-101110-1 },//상 왼 하 오
dy[] = { 0-1-1-10111 };
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(000);
    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