알고리즘 문제 풀이/BOJ

[BOJ 16235] 나무 재테크

JOngNan 2018. 10. 24. 17:51

# 문제


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


# 풀이


일단, 굉장히 구현스러운 문제... 그냥 문제 따라서 가면서 코드를 짜면 된다.


여기서 조심할점은..... 나무의 위치를 주어질때! x,y 가아닌 y,x 순으로 주어진다는 것이다.....

이점을 명시하자.... 


1년차에는 기본적으로 양분이 모두  5로 되어있기 때문에 1년차와 아닐때를 나누어 알고리즘을 짯다.

1년차에는 기본적으로 주어진 양분을 사용, 2~K년차까지는 여태 남아있는 양분을 사용!

이런식으로 기본적 양분을 넣어줄 2차원 배열, 매년마다 추가로 들어가는 양분을 저장해줄 2차원 배열, 최종으로 남게 되는 양분 2차원 배열 3개를 만들어 사용하였다.


우선 순위 큐를 사용해도 되지만, 벡터를 사용하였다.

큐 사용할때 넣고 빼고 이런게 너무 귀찮아서... 그냥 인덱스로 하는게 편해서 그렇게 하였다.


벡터에 저장할 때도 Tree라는 구조체를 만들어 주어 넣어 주었다.

Tree 구조체에는 위치, 나이, 죽었는지의 여부가 들어가있다.


처음에 나이를 죽었을때 -1로 주어 할려했지만, 봄에 죽는다 치면 여름에 그 나이를 사용해야하므로 따로 어디다 저장을 해야하던가 해야 된다. 그러다 보니 여름에 나무가 죽어 양분을 줄때, 만들어준 배열에 반영이 되지 않았다. 이점을 처음에 놓쳐 좀 헤메긴했다.... 주의하도록 하자!


모든 시즌마다 행동을 끝내고 죽은 나무들만 걸러 저장해 놓았던 벡터를 갱신시켰다.


여기서 주의 할 점!!

양분을 먹을때, 나이가 어린 순서대로 양분을 먹게 되므로 갱신을 시킬때, 나이 순으로 sort를 해주었다.

이렇게 해놓으면 위치와 상관없이 나이 순서대로 먹게 되므로 해당 조건을 만족할 수있게 된다.


# 코드


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
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
 
struct Tree{
    int r,c;
    int age = 1;
    bool dead = false;
};
 
bool compare(Tree a, Tree b){
    return a.age < b.age;
}
 
int N,M,K;
 
int startEnergy[11][11];
int yearEnergy[11][11];
int totalEnergy[11][11];
 
int dr[8= {-1,-1,-1,0,0,1,1,1};
int dc[8= {-1,0,1,-1,1,-1,0,1};
 
void initEnergy(){
    for(int i = 1; i <= 10; i++){
        for(int j = 1; j <= 10; j++){
            startEnergy[i][j] = 5;
            yearEnergy[i][j] = 0;
            totalEnergy[i][j] = 0;
        }
    }
}
 
int main(){
    initEnergy();
    cin >> N >> M >> K;
    for(int i = 1; i <= N; i++){
        for(int j = 1; j <= N; j++){
            cin >> yearEnergy[i][j];
        }
    }
    vector<Tree> trees;
    for(int i = 0; i < M; i++){
        Tree tree;
        cin >> tree.r >> tree.c >> tree.age;
        trees.push_back(tree);
    }
    int year = 1;
    while(year <= K){
        for(int season = 1; season <= 4; season++){
            if(season == 1){
                if(year == 1){
                    for(unsigned int i = 0; i < trees.size(); i++){
                        if(startEnergy[trees[i].r][trees[i].c] < trees[i].age){
                            trees[i].dead = true;
                        }else{
                            startEnergy[trees[i].r][trees[i].c] -= trees[i].age;
                            trees[i].age++;
                        }
                    }
                }else{
                    for(unsigned int i = 0; i < trees.size(); i++){
                        if(totalEnergy[trees[i].r][trees[i].c] < trees[i].age){
                            trees[i].dead = true;
                        }else{
                            totalEnergy[trees[i].r][trees[i].c] -= trees[i].age;
                            trees[i].age++;
                        }
                    }
                }
            }else if(season == 2){
                if(year == 1){
                    for(unsigned int i = 0; i < trees.size(); i++){
                        if(trees[i].dead){
                            startEnergy[trees[i].r][trees[i].c] += (trees[i].age/2);
                        }
                    }
                }else{
                    for(unsigned int i = 0; i < trees.size(); i++){
                        if(trees[i].dead){
                            totalEnergy[trees[i].r][trees[i].c] += (trees[i].age/2);
                        }
                    }
                }
            }else if(season == 3){
                for(unsigned int i = 0; i < trees.size(); i++){
                    if(trees[i].dead) continue;
                    if(trees[i].age % 5 == 0){
                        int cnt = 0;
                        for(int dir = 0; dir < 8; dir++){
                            int nTreeR = trees[i].r + dr[dir];
                            int nTreeC = trees[i].c + dc[dir];
                            if(nTreeR < 1 || nTreeR > N || nTreeC < 1 || nTreeC > N) continue;
                            Tree newTree;
                            newTree.r = nTreeR;
                            newTree.c = nTreeC;
                            trees.push_back(newTree);
                            cnt++;
                        }
                    }
                }
            }else{
                if(year == 1){
                    for(int i = 1; i <= N; i++){
                        for(int j = 1; j <= N; j++){
                            totalEnergy[i][j] = startEnergy[i][j] + yearEnergy[i][j];
                        }
                    }
                }else{
                    for(int i = 1; i <= N; i++){
                        for(int j = 1; j <= N; j++){
                            totalEnergy[i][j] = totalEnergy[i][j] + yearEnergy[i][j];
                        }
                    }
                }
            }
        }
        vector<Tree> temp;
        temp.assign(trees.begin(), trees.end());
        trees.clear();
        sort(temp.begin(), temp.end(), compare);
        for(unsigned int i = 0; i < temp.size(); i++){
            if(!temp[i].dead){
                trees.push_back(temp[i]);
            }
        }
        year++;
    }
    int ans = (int)trees.size();
    cout << ans << endl;
    return 0;
}
 
cs