안녕하세요. 이번 포스팅에서는 백준 16235번 나무 재테크 문제를 풀어보겠습니다.
https://www.acmicpc.net/problem/16235
16235번: 나무 재테크
부동산 투자로 억대의 돈을 번 상도는 최근 N×N 크기의 땅을 구매했다. 상도는 손쉬운 땅 관리를 위해 땅을 1×1 크기의 칸으로 나누어 놓았다. 각각의 칸은 (r, c)로 나타내며, r은 가장 위에서부터
www.acmicpc.net
해당 문제는 위 링크에서 확인하실 수 있습니다.
우선 이 문제를 풀기 위해 별도의 알고리즘을 많이 고민하실 필요는 없습니다.
해당 문제를 시뮬레이션으로 구현하시면 되는데, 문제는 이 문제의 제한이 빡빡합니다. 시간제한이 0.3초라서, 매번 sort를 하기 어렵습니다.
sort를 하는 이유는 어린 나무부터 양분을 먹기 위해서입니다.
따라서 효율적으로 양분을 먹이고, 죽은 나무에 대한 처리과정을 진행해주셔야 합니다.
저 같은 경우는
봄&여름 : 현재 나무들이 저장된 벡터를 순회하며, 죽지 않는 나무는 newV에 넣고, 죽은 나무는 death라는 vector에 넣었습니다.
죽지 않은 나무의 경우 양분을 나이만큼 빼 주었고, 나이를 1 증가시켜주었습니다.
죽은 나무의 경우 나이/2를 더해 주었습니다.
가을&겨울 : 가을의 경우 추가하려는 나무의 인덱스가 넘어가는 지 확인(1)을 한 뒤, 추가할 수 있으면 벡터의 앞부분에 넣어주었습니다. 추가되는 나무는 나이가 1로 고정이기 때문에 추가적인 sort를 하지 않고자 앞부분에 넣었습니다.
또한 벡터의 앞부분에 넣는 연산을 v.insert(v.begin(), a)로 수행할 수 있는데, 해당 문법을 사용하시면 시간이 오래 걸립니다.
따라서 tmp배열을 하나 만들어서 새로 추가되는 나무들을 저장한 뒤, vector의 원소는 이미 정렬되어 있으므로 tmp배열 뒤에 추가만 해주었습니다.
<소스 코드>
#include <bits/stdc++.h>
using namespace std;
int n, m, k, board[14][14], A[14][14];
const int dir[8][2] = {{-1,-1}, {-1,0}, {-1,1}, {0,-1}, {0, 1}, {1, -1}, {1, 0}, {1,1}};
typedef struct tree{
int y,x,z;
}TREE;
vector<TREE> v;
bool cmp(TREE a, TREE b) {
if(a.z != b.z) return a.z <= b.z;
return 0;
}
void springAndSummer() {
vector<TREE> death;
vector<TREE> newV;
for(int i = 0; i < v.size(); i++) {
int y=v[i].y, x=v[i].x, age=v[i].z;
if(board[y][x] >= age) {
board[y][x]-=age;
v[i].z++;
newV.push_back(v[i]);
} else death.push_back(v[i]);
}
for(int i = 0; i < death.size(); i++) board[death[i].y][death[i].x]+=(death[i].z/2);
v=newV;
}
void autumnAndWinter() {
vector<TREE> tmp;
for(int i = 0; i < v.size(); i++) {
int y=v[i].y, x=v[i].x, age=v[i].z;
if(age%5==0) {
for(int d = 0; d < 8; d++) {
int ny = y+dir[d][0], nx = x+dir[d][1];
if(ny < 1 || nx < 1 || ny > n || nx > n) continue;
tmp.push_back({ny,nx,1});
}
}
}
for(auto a : v) tmp.push_back(a);
v = tmp;
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= n; j++) board[i][j] += A[i][j];
}
}
int main() {
ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
cin >> n >> m >> k;
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= n; j++) cin >> A[i][j];
}
for(int i = 0; i < m; i++) {
int a, b, c; cin >> a >> b >> c;
v.push_back({a, b, c});
}
fill(&board[0][0], &board[0][0]+14*14, 5);
sort(v.begin(), v.end(), cmp);
while(k--) {
springAndSummer();
autumnAndWinter();
}
cout << v.size() << '\n';
return 0;
}
*저의 글에 대한 피드백이나 지적은 언제나 환영합니다.
'Algorithm > BeakJoon' 카테고리의 다른 글
[BeakJoon 17623] 괄호 (0) | 2021.08.22 |
---|---|
[BeakJoon 2618] 경찰차 (0) | 2021.08.18 |
[BeakJoon 17070] 파이프 옮기기1 (0) | 2021.08.10 |
[BeakJoon 1700] 멀티탭 스케줄링 (0) | 2021.08.09 |
[BeakJoon 15685] 드래곤 커브 (0) | 2021.08.01 |