내 세상

[Algorithm] 백준 16235번 나무 재테크 본문

Coding/Algorithms

[Algorithm] 백준 16235번 나무 재테크

sga8 2019. 2. 21. 01:07
728x90
반응형


https://www.acmicpc.net/problem/16235


문제 자체에는 어려움이 없음.

하지만, vector의 시간 복잡도에 대해서 이해가 부족하여 오래 잡았음.

앞으로 vector를 사용할 때는 sort 외에는 별도로 이용하지 않아야 겠다!!



문제 풀이 및 이슈 정리

1. (x, y) 가 있을 때, x를 행의 위치 그리고 y를 열의 위치로 하였음.

   → 백준 사이트 내 이슈를 확인하니, 행과 열이 헷갈린다는 말이 있으나 문제를 제대로 보면 그럴 리 없음.

2. 죽은 나무들을 vector erase로 처리하려고 하면, erase의 시간 복잡도가 O(N)이기 때문에 time out 발생함.

   이를 해결하기 위해 봄과 여름을 합치고 가을부터 살아남은 나무로 구성된 vector array를 사용하여 진행함.

3. 애초에 vector erase를 사용하게 되면, 하나씩 지울때마다 배열 내 위치와 전체 크기가 수정됨. 

   시간 복잡도가 심각하기 때문에 굳이 돌아가지 말고, 앞으로도 별도 배열로 추후에 처리하는 것이 좋을듯.



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
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
#include <math.h>
using namespace std;
 
struct Point {
    int x;
    int y;
    Point() : x(0), y(0) {}
    Point(int x, int y) : x(x), y(y) {}
};
 
vector < vector < int > > ground;
vector < vector < int > > s2d2;
vector < pair < Point, int > > tree;
 
bool compPoint(const pair < Point, int > &a, const pair < Point, int > &b) {
    if (a.second < b.second) return true;
    return false;
}
int main()
{
    // N : A 배열의 값
    // M : 나무의 개수
    // K : K 년
    int N, M, K;
    cin >> N >> M >> K;
    ground.assign(N, vector<int>(N, 5));
    s2d2.assign(N, vector<int>(N, 0));
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++) {
            cin >> s2d2[i][j];
        }
    }
    int tx, ty, tv;
    for (int i = 0; i < M; i++) {
        cin >> tx >> ty >> tv;
        tree.push_back(make_pair(Point(tx - 1, ty - 1), tv));
    }
 
    // 1 YEAR
    // 봄 : 나무가 자신의 나이만큼 양분 먹고, 나이 + 1
    //      어린 나무 부터 먹고, 못 먹으면 죽음.
    // 여름 : 봄에 죽은 나무가 양분으로 변하게 됨. 
    //        나이 / 2 만큼 양분이 쌓임. (소수점 버림)
    // 가을 : 나이가 5의 배수인 나무가 8방향으로 번식함.
    // 겨울 : s2d2가 양분을 뿌림.
 
    int dx[8= { -1,-1,-1,0,1,1,1,0 };
    int dy[8= { -1,0,1,1,1,0,-1,-1 };
    while (K != 0 && tree.size() != 0) {
 
        // 봄, 여름
        vector < pair < Point, int > > tempTree;
        vector < int > deadTree;
        sort(tree.begin(), tree.end(), compPoint);
        int treeCount = tree.size();
        for (int i = 0; i < treeCount; i++) {
            Point tPoint = tree[i].first;
            int tValue = tree[i].second;
            if (ground[tPoint.x][tPoint.y] >= tValue) {
                ground[tPoint.x][tPoint.y] -= tValue;
                tree[i].second += 1;
                tempTree.push_back(tree[i]);
            }
            else {
                deadTree.push_back(i);
            }
        }
 
        
        int deadTreeCount = deadTree.size();
        for (int i = 0; i < deadTreeCount; i++) {
            Point tPoint = tree[deadTree[i]].first;
            int tValue = tree[deadTree[i]].second;
            ground[tPoint.x][tPoint.y] += tValue / 2;
        }
 
 
        // 가을
        treeCount = tempTree.size();
        for (int i = 0; i < treeCount; i++) {
            Point tPoint = tempTree[i].first;
            int tValue = tempTree[i].second;
            if (tValue % 5 == 0) {
                int cx, cy;
                for (int k = 0; k < 8; k++) {
                    cx = tPoint.x + dx[k];
                    cy = tPoint.y + dy[k];
                    if (cx >= 0 && cy >= 0 && cx < N && cy < N) {
                        tempTree.push_back(make_pair(Point(cx, cy), 1));
                    }
                }
            }
        }
 
        // 겨울
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                ground[i][j] += s2d2[i][j];
            }
        }
 
        // 죽은 트리 없애고 수정하기.
        tree.clear();
        tree = tempTree;
        K--;
    }
 
    cout << tree.size();
    return 0;
}
cs




행복하세요 화이팅

 




728x90
반응형