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

Life Engineering

[BOJ 16235] 나무 재테크 (C++) 본문

Problem Solving

[BOJ 16235] 나무 재테크 (C++)

흑개 2021. 10. 12. 22:14

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

 

16235번: 나무 재테크

부동산 투자로 억대의 돈을 번 상도는 최근 N×N 크기의 땅을 구매했다. 상도는 손쉬운 땅 관리를 위해 땅을 1×1 크기의 칸으로 나누어 놓았다. 각각의 칸은 (r, c)로 나타내며, r은 가장 위에서부터

www.acmicpc.net

#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;

struct Trees {
	vector<int> list;
};

int N, M, K;
int A[11][11];
int food[11][11];
struct Trees graph[11][11];

int dx[8] = { -1,-1,-1,0,0,1,1,1 };
int dy[8] = { -1,0,1,-1,1,-1,0,1 };

void springnsummer() {
	for (int i = 1; i <= N; i++) {
		for (int j = 1; j <= N; j++) {
			if (!graph[i][j].list.empty()) {
				sort(graph[i][j].list.begin(), graph[i][j].list.end());
				int sum = 0;
				for (int k = 0; k< graph[i][j].list.size(); k++) {
					int age = graph[i][j].list[k];
					if (food[i][j] < age) {
						sum += (age / 2);
						graph[i][j].list.erase(graph[i][j].list.begin()+k);
						k--;
					}
					else {
						food[i][j] -= age;
						graph[i][j].list[k] += 1;
					}
				}
				food[i][j] += sum;
			}
		}
	}
}

void fall() {
	for (int i = 1; i <= N; i++) {
		for (int j = 1; j <= N; j++) {
			if (!graph[i][j].list.empty()) {
				for (int age : graph[i][j].list) {
					if (age % 5 == 0) {
						for (int k = 0; k < 8; k++) {
							int nx = i + dx[k]; int ny = j + dy[k];
							if (nx >= 1 && nx <= N && ny >= 1 && ny <= N) {
								graph[nx][ny].list.push_back(1);
							}
						}
					}
				}
			}
		}
	}
}

void winter() {
	for (int i = 1; i <= N; i++) {
		for (int j = 1; j <= N; j++) {
			food[i][j] += A[i][j];
		}
	}
}

int main() {
	int x, y, z;
	int ans = 0;
	cin >> N >> M >> K;
	for (int i = 1; i <= N; i++) {
		for (int j = 1; j <= N; j++) {
			cin >> A[i][j];
			food[i][j] = 5;
		}
	}
	for (int i = 0; i < M; i++) {
		cin >> x >> y >> z;
		graph[x][y].list.push_back(z);
	}
	for (int i = 0; i < K; i++) {
		springnsummer();
		fall();
		winter();
	}
	for (int i = 1; i <= N; i++) {
		for (int j = 1; j <= N; j++) {
			ans += graph[i][j].list.size();
		}
	}
	cout << ans << "\n";
	return 0;
}

 

구현 문제.

 

자료구조를 어떻게 할 것인가 고민했는데 각 칸=struct trees로 구성하고, struct trees 안의 요소를 vector로 구성하여 여러개의 나무를 담을 수 있도록 했다.

 

age를 비교해서 food보다 작거나 같다면 food를 age만큼 감소시키고, age는 +1 해준다.

food보다 크다면 죽은 나무의 나이/2 를 저장하고 해당 나무를 벡터에서 제거한다. 하나가 감소했으므로 k-- 해줘서 다음 것도 탐색할 수 있도록 한다. 

나무의 갯수는 모든 K년의 계산을 마친 후 배열을 체크해서 구한다.

 

다른 분들 코드를 보니,

deque<int> graph[10][10]; 이런 식으로 자료구조를 해줘서 각 좌표에 deque로 나무들을 담을 수 있도록 한다.

그리고 양분이 적어 먹을 수 없는 나무의 경우일 때,  deque가 빌 때까지 deque에 pop_back() 해주고, back()/2 해줘서 원하는 값을 구한다. 별도로 정렬하지 않고 덱만을 써도 되는 이유는 "입력으로 주어지는 나무의 위치는 모두 서로 다름"의 조건이 있기 때문이다. 

'Problem Solving' 카테고리의 다른 글

[BOJ 17417] 게리맨더링 (C++)  (0) 2021.10.16
[BOJ 16637] 괄호 추가하기 (C++)  (0) 2021.10.14
[BOJ 10819] 차이를 최대로 (C++)  (0) 2021.10.12
[BOJ 9663] N-Queen (C++)  (0) 2021.10.12
[BOJ 15684] 사다리 조작 (C++)  (0) 2021.10.11