[백준 19237번] 어른 상어

2022. 4. 4. 03:52·알고리즘 문제풀이/백준
반응형

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

 

19237번: 어른 상어

첫 줄에는 N, M, k가 주어진다. (2 ≤ N ≤ 20, 2 ≤ M ≤ N2, 1 ≤ k ≤ 1,000) 그 다음 줄부터 N개의 줄에 걸쳐 격자의 모습이 주어진다. 0은 빈칸이고, 0이 아닌 수 x는 x번 상어가 들어있는 칸을 의미

www.acmicpc.net

<문제 풀이> BFS
이문제는 상어의 방향 정보를 클래스로 묶어서 관리하면 간단하게 해결할 수 있습니다.

그런데 주의할 점은 상어가 이동할 때 여러 상어가 겹치는 부분을 처리해야 하는데 이때 상어를 한 마리씩 이동시킬 때 바로 이동 상태를 맵에 반영하는 게 아니라 임시 큐를 하나 생성해서 임시로 이동시킨 후 번호가 낮은 상어만 맵에 반영해야 합니다.

그리고 또 주의할 점 하나는 시간이 1000초 일 때 상어가 2마리 이상이면 -1을 리턴해야합니다.

<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
136
137
138
139
140
141
142
143
144
145
146
147
#include<iostream>
#include<queue>
#include<utility>
#include<algorithm>
using namespace std;
 
#define X first
#define Y second
 
#define NUM first
#define SMELL second
 
class shark {
public:
    int curDir;
    int nextDir[5][5];
    void del() {
        curDir = -1;
    }
    bool exist() {
        return curDir != -1;
    }
    
};
shark info[401];
int N, M, K;
int board[20][20];
pair<int, int> visited[20][20];
queue<pair<int, int > > Q;
const int dx[5] = {0, -1, 1, 0, 0};
const int dy[5] = {0, 0 , 0, -1, 1};
int tot_shark;
 
void decreaseSMELL() {
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++) {
            if (visited[i][j].SMELL && !board[i][j]) {
                visited[i][j].SMELL--;
            }
            
        }
    }
}
 
int bfs() {
    int t = 0;
    while (!Q.empty()) {
        int Q_size = Q.size();
        queue<pair<int, int> > tempQ; //임시로 다음 상어를 이동 시킴
        queue<int> num; //임시로 이동 시킨 상어의 번호
    
        for (int i = 0; i < Q_size; i++) {
            auto cur = Q.front(); Q.pop();
            if (!info[board[cur.X][cur.Y]].exist())continue;
            bool flag = false; //냄새가 없는 곳을 찾으면 true
            for (int dir = 1; dir <= 4; dir++) {
                shark s = info[board[cur.X][cur.Y]];
                int nx = cur.X + dx[s.nextDir[s.curDir][dir]];
                int ny = cur.Y + dy[s.nextDir[s.curDir][dir]];
                if (nx < 0 || ny < 0 || nx >= N || ny >= N) continue;
                if (visited[nx][ny].SMELL)continue;
                Q.push({ nx, ny });
                tempQ.push({ nx, ny });
                num.push(board[cur.X][cur.Y]);
                info[board[cur.X][cur.Y]].curDir = s.nextDir[s.curDir][dir];
                board[cur.X][cur.Y] = 0;
                flag = true;
                break;
            }
            if (!flag) { // 만약 냄새가 없는 곳이 없으면 자기 냄새가 있는 공간을 찾아서 이동
                for (int dir = 1; dir <= 4; dir++) {
                    shark s = info[board[cur.X][cur.Y]];
                    int nx = cur.X + dx[s.nextDir[s.curDir][dir]];
                    int ny = cur.Y + dy[s.nextDir[s.curDir][dir]];
                    if (nx < 0 || ny < 0 || nx >= N || ny >= N) continue;
                    if (visited[nx][ny].NUM == visited[cur.X][cur.Y].NUM) {
                        tempQ.push({ nx, ny });
                        Q.push({ nx, ny });
                        num.push(board[cur.X][cur.Y]);
                        info[board[cur.X][cur.Y]].curDir = s.nextDir[s.curDir][dir];
                        board[cur.X][cur.Y] = 0;
                        flag = true;
                        break;
                    }
                }
            }
        }
        while (!tempQ.empty()) {
            auto cur = tempQ.front(); tempQ.pop();
            int n = num.front(); num.pop();
            if (board[cur.X][cur.Y]) { //상어가 겹치면
                if (n < board[cur.X][cur.Y]) { // 더 작은 번호의 상어만 살아 남는다
                    info[board[cur.X][cur.Y]].del();
                    board[cur.X][cur.Y] = n;
                    visited[cur.X][cur.Y].SMELL = K;
                    visited[cur.X][cur.Y].NUM = n;
                    
                } 
                tot_shark--; //상어 한 마리 죽이기
            }
            else {
                board[cur.X][cur.Y] = n;
                visited[cur.X][cur.Y].SMELL = K;
                visited[cur.X][cur.Y].NUM = n;
            }
        }
        decreaseSMELL();
        t++;
        if (tot_shark == 1) return t;
        if (t >= 1000) return -1;
     
    }
}
 
 
 
int main(void) {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL); cout.tie(NULL);
 
    cin >> N >> M >> K;
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++) {
            cin >> board[i][j];
            if (board[i][j] != 0) {
                visited[i][j].NUM = board[i][j];
                visited[i][j].SMELL = K;
                Q.push({ i, j });
                tot_shark++;
            }
        }
    }
    for (int i = 1; i <= M; i++) {
        cin >> info[i].curDir;
    }
    for (int i = 1; i <= M; i++) {
        for (int j = 1; j <= 4; j++) {
            cin >> info[i].nextDir[j][1];
            cin >> info[i].nextDir[j][2];
            cin >> info[i].nextDir[j][3];
            cin >> info[i].nextDir[j][4];
        }
    }
    info[0].del();
    cout<<bfs();
    return 0;
}
Colored by Color Scripter
cs

 

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

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

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

    • 홈
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

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

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
슥지니
[백준 19237번] 어른 상어
상단으로

티스토리툴바