Notice
Recent Posts
Recent Comments
Link
«   2024/05   »
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
Tags
more
Archives
Today
Total
관리 메뉴

혼종 꼬지마루

[백준] 17144 - 미세먼지 안녕! 본문

Algorithms/SIMULATION

[백준] 17144 - 미세먼지 안녕!

꼬지마루 2019. 4. 21. 14:34

망할 미세먼지 때문에 내 차가 세차를 해도 일주일을 못가는거 같다...ㅂㄷㅂㄷ

일단 망할 미세먼지가 퍼지는건 구현하기 위해서도 구조체 배열로 저장하는게 좋기도 하고... 좀 비효율적인거 같기도 하고

일단 이 문제는 공기청정기를 돌리는 과정에서 너무 구현하기 귀찮아서 한 10번은 코드짜다 지웠다 한거같다

어떻게든 덜 귀찮게 짜려고...그래도 일단은 일전에 풀었던 블록게임에서 아이디어를 얻었다...

DFS로 좌표 끝까지 가고 돌아오면서 갱신하는 방법을 사용


1. 먼저 먼지가 퍼질 수 있는 조건 map[i][j] / 5가 1이상인 지점을 구조체 배열을 만들어 좌표와 그 값을 저장


2. 미세먼지가 저장된 구조체 배열에서 하나씩 꺼내어 4방향 검사하는데, 이때 먼지가 못퍼지는 경우(공기청정기 or 배열 범위 초과)는 퍼트리지 않는다

- 구조체 배열에 저장하는 이유는 바로 map에서 퍼트릴 경우엔 다음 퍼트릴 먼지에 영향이 갈 것이라고 생각했기 때문이다.

- 낚시왕처럼 tmp배열을 만들고도 싶었으나 시간이 굉장히 길어지면...시간 복잡도가 엄청 뛸 것이라고 생각함


3. 이렇게 먼지를 한번 퍼트리고 나면 이제 공기청정기를 돌려주기 위해 재귀함수로 한바퀴 돌려준다

- 방향 전환이 필요할 경우에는 다른 방법이 있을 수 있겠으나, 2칸의 공기청정기를 따로 돌려주기 때문에 그냥 좌표와 조건에 따라 임의로 방향을 바꿔줌


4. 좌표 끝까지 도달했다면, 리턴하며 map의 값을 바꿔준다

- 이때, 맨끝점을 제외하고는 현재 map의 값을 따로 저장하고, 갱신 후 저장된 값을 리턴해야한다


5. 이 순서로 T번 반복하고 그냥 for문으로 map을 전부 순회하며 먼지들을 다 더하고 출력은 +2를 한다

- 공기청정기 -1이 두개 있기 때문


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
#include <iostream>
#define MAXSIZE 52
using namespace std;
 
struct AIR {
    int x, y, dust;
}air[2], dust_[MAXSIZE*MAXSIZE];
 
int map[MAXSIZE][MAXSIZE];
int dx[] = { 00-11 };
int dy[] = { -1100 };
int N, M, T, dab;
 
int dfs(int d, int x, int y, int dir, int air_num) {
    if (d != 0 && map[y][x] == -1return 0;
    if (air_num == 0) {
        if (y == 0 && dir == 0) { dir = 3; }
        else if (x == M - 1 && dir == 3) { dir = 1; }
        else if (y == air[air_num].y && dir == 1) { dir = 2; }
    }
    if (air_num == 1) {
        if (y == N - 1 && dir == 1) { dir = 3; }
        else if (x == M - 1 && dir == 3) { dir = 0; }
        else if (y == air[air_num].y && dir == 0) { dir = 2; }
    }
    int nx = x + dx[dir], ny = y + dy[dir];
    int ret = map[y][x];
    map[y][x] = dfs(d + 1, nx, ny, dir, air_num);
    return ret;
}
 
int main(void) {
    cin >> N >> M >> T;
    int air_cnt = 0;
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < M; j++) {
            cin >> map[i][j];
            if (map[i][j] == -1) { air[air_cnt].x = j; air[air_cnt].y = i; air_cnt++; }
        }
    }
    for (int t = 1; t <= T; t++) {
    
        int dust_cnt = 0;
        for (int i = 0; i < N; i++) { // 뿌려질 먼지가 있는 곳을 search
            for (int j = 0; j < M; j++) {
                if (map[i][j] && (map[i][j] / 5 >= 1)) {
                    dust_[dust_cnt].x = j; dust_[dust_cnt].y = i; dust_[dust_cnt].dust = map[i][j]; dust_cnt++;
                }
            }
        }
 
        for (int i = 0; i < dust_cnt; i++) { //먼지 퍼트리기
            int ix = dust_[i].x, iy = dust_[i].y, d_dust = dust_[i].dust / 5;
            for (int d = 0; d < 4; d++) {
                int nx = ix + dx[d], ny = iy + dy[d];
                if (nx < 0 || ny < 0 || nx >= M || ny >= N || map[ny][nx] == -1continue;
                map[ny][nx] += d_dust;    map[iy][ix] -= d_dust;
            }
        }
        map[air[0].y][air[0].x] = dfs(0, air[0].x, air[0].y, 00);
        map[air[1].y][air[1].x] = dfs(0, air[1].x, air[1].y, 11);
    }
    for (int y = 0; y < N; y++)
        for (int x = 0; x < M; x++)
            dab += map[y][x];
    cout << dab + 2 << endl;
    return 0;
}
cs


'Algorithms > SIMULATION' 카테고리의 다른 글

[벡준] 3954 - Brainf**k 인터프리터  (2) 2019.10.09
[백준] 17140 - 이차원 배열과 연산  (0) 2019.07.27
[백준] 17143 - 낚시왕  (4) 2019.04.21
[백준] 12793 - 블록 게임  (0) 2019.04.13
[백준] 13337 - 트럭  (0) 2019.04.12