[백준 19236번] 청소년 상어

2022. 4. 3. 01:20·알고리즘 문제풀이/백준
반응형

문제 링크: https://www.acmicpc.net/problem/19236

 

19236번: 청소년 상어

첫째 줄부터 4개의 줄에 각 칸의 들어있는 물고기의 정보가 1번 행부터 순서대로 주어진다. 물고기의 정보는 두 정수 ai, bi로 이루어져 있고, ai는 물고기의 번호, bi는 방향을 의미한다. 방향 bi는

www.acmicpc.net

<문제 풀이> 백 트랙킹

이 문제는 백트래킹을 할 때 상태 정보 백업 및 복원이 가장 핵심입니다.

상어를 1칸 이동, 2칸 이동, 3칸 이동시키고 각각에 대해서 재귀 호출할 때 재귀 호출 전에 백업, 호출 후 복원을 하면 되고, 물고기들이 이동하는 건 클래스로 좌표와 방향을 저장해 두고 1번부터 16번까지 단순히 움직이면 됩니다.

 

이때 주의할 점은 상어는 물고기가 있는 칸만 이동할 수 있습니다.
(2칸에 물고기가 없다고 끝내면 안 되고 3칸도 이동해 보아야 한다.)

 

 

 

<C++ 소스 코드>

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
#include<iostream>
#include<algorithm>
using namespace std;
 
#define SHARK -1
#define EMPTY -2
class pos {
public:
    int x, y, dir;
    void rotate() {
        dir++;
        if (dir == 9) dir = 1;
 
    }
    void del() {
        x = -1; y = -1; dir = -1;
    }
    bool exist() {
        if (x == -1 && y == -1 && dir == -1) return false;
        else return true;
    }
};
 
const int dx[9] = {0, -1, -1, 0, 1, 1, 1, 0, -1};
const int dy[9] = {0, 0, -1, -1, -1, 0, 1, 1, 1};
 
pos info[17]; //1~16번 좌표 방향 정보
int board[4][4];
pos shark; //현재 상어 상태
int res = 0;
void move() {
    for (int i = 1; i <= 16; i++) {
        if (!info[i].exist()) continue;
        int startDir = info[i].dir;
        while (true) {
            int nx = info[i].x + dx[info[i].dir];
            int ny = info[i].y + dy[info[i].dir];
            int next = board[nx][ny];
            if (nx < 0 || ny < 0 || nx >= 4 || ny >= 4 || board[nx][ny] == SHARK) {
                info[i].rotate();
                if (startDir == info[i].dir)break;
                continue;
            }
            if (board[nx][ny] == EMPTY) {
                board[nx][ny] = i;
                board[info[i].x][info[i].y] = EMPTY;
                info[i].x = nx;
                info[i].y = ny;
            }
            else {
                swap(board[info[i].x][info[i].y], board[nx][ny]);
                swap(info[i], info[next]);
                swap(info[i].dir, info[next].dir);
            }
            break;
        }
    }
}
 
/*백트랙킹 상태 정보 백업용*/
void backupBoard(int des[4][4], int src[4][4]) {
    for (int i = 0; i < 4; i++) {
        for (int j = 0; j < 4; j++) {
            des[i][j] = src[i][j];
        }
    }
}
void backupInfo(pos des[17], pos src[17]) {
    for (int i = 0; i < 17; i++) {
        des[i] = src[i];
    }
}
 
 
void solve(int sum) {
    move();
    int cx = shark.x;
    int cy = shark.y;
    int dir = shark.dir;
 
    for (int k = 1; k <= 3; k++) {
        int nx = cx + dx[dir] * k;
        int ny = cy + dy[dir] * k;
        if (nx < 0 || ny < 0 || nx >= 4 || ny >= 4) return;
        if (board[nx][ny] == EMPTY) continue;
        int tempBoard[4][4];
        pos tempInfo[17];
        backupBoard(tempBoard, board);
        backupInfo(tempInfo, info);
        shark.x = nx;
        shark.y = ny;
        int num = board[nx][ny];
        res = max(res, sum + num);
        shark.dir = info[num].dir;
        board[nx][ny] = SHARK;
        board[cx][cy] = EMPTY;
        info[num].del();
 
        solve(sum + num);
        
        shark.x = cx;
        shark.y = cy;
        shark.dir = dir;
        backupBoard(board, tempBoard);
        backupInfo(info, tempInfo);
    }    
}
 
int main(void) {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL); cout.tie(NULL);
 
    for (int i = 0; i < 4; i++) {
        for (int j = 0; j < 4; j++) {
            int a, b;
            cin >> a >> b;
            info[a].dir = b;
            info[a].x = i;
            info[a].y = j;
            board[i][j] = a;
        }
    }
 
    shark.x = 0;
    shark.y = 0;
    shark.dir = info[board[0][0]].dir;
 
    info[board[0][0]].del();
    int num  = board[0][0];
    board[0][0] = SHARK;
    solve(num);
    cout << res;
    
    return 0;
}
Colored by Color Scripter
cs

 

반응형
저작자표시 (새창열림)

'알고리즘 문제풀이 > 백준' 카테고리의 다른 글

[백준 1932번] 정수 삼각형  (0) 2022.05.06
[백준 19237번] 어른 상어  (0) 2022.04.04
[백준 16236번] 아기 상어  (0) 2022.03.30
[백준 17142번] 연구소 3  (0) 2022.03.30
[백준 20055번] 컨베이어 벨트 위의 로봇  (0) 2022.03.26
'알고리즘 문제풀이/백준' 카테고리의 다른 글
  • [백준 1932번] 정수 삼각형
  • [백준 19237번] 어른 상어
  • [백준 16236번] 아기 상어
  • [백준 17142번] 연구소 3
슥지니
슥지니
개발 블로그
  • 슥지니
    슥지니의 코딩노트
    슥지니
  • 전체
    오늘
    어제
    • 분류 전체보기 (198)
      • 알고리즘 문제풀이 (158)
        • 백준 (158)
      • 알고리즘 (6)
      • Node.js (2)
        • MongoDB (1)
        • 기타 (1)
      • spring (0)
      • 가상화폐 (1)
        • 바이낸스(Binance) (1)
      • C++ 테트리스 게임 (0)
      • C++ (10)
      • 안드로이드 프로그래밍 (21)
        • 코틀린 (21)
  • 블로그 메뉴

    • 홈
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    dfs
    백트랙킹
    알고리즘
    우선순위 큐
    구현
    시뮬레이션
    코틀린
    C++
    그래프
    자료구조
    콘솔 테트리스 게임
    코틀린을 활용한 안드로이드 프로그래밍
    Kotlin
    dp
    콘솔
    BFS
    백준
    다이나믹 프로그래밍
    그리디
    C
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
슥지니
[백준 19236번] 청소년 상어
상단으로

티스토리툴바