-
[16235] 나무 재테크BOJ 2021. 9. 1. 22:42
https://www.acmicpc.net/problem/16235
16235번: 나무 재테크
부동산 투자로 억대의 돈을 번 상도는 최근 N×N 크기의 땅을 구매했다. 상도는 손쉬운 땅 관리를 위해 땅을 1×1 크기의 칸으로 나누어 놓았다. 각각의 칸은 (r, c)로 나타내며, r은 가장 위에서부터
www.acmicpc.net
<문제>
문제가 길고, 구현해야 하는 것도 많다. 대략 다음을 구현해야 하는 문제이다.
1. 하나의 칸에 여러개의 나무가 존재할 수 있으며, 같은 칸중 어린나무부터 양분을 자신의 나이만큼 먹는다.
1-1 : 먹을 양분이 없다면, 나무는 죽고 죽은 나무가 양분이된다.
1-2 : 먹을 양분이 있다면, 나무는 양분을 먹고 나이가 1 증가한다.
2. 나이가 5의 배수일때, 인접한 칸에 나이1의 나무를 생성한다.
그외에는 맵에 단순한 연산으로 커버할 수 있다. 이제 구현해야하는걸 하나씩 따져보자.
1. '하나의 칸에 여러개의 나무가 존재할 수 있다' -> 3차원으로 관리해주어야 한다. 이를 조금 더 편리하게 관리하기 위해서 vector<int>tree[][]의 형태로 선언하였다.
2. 같은 칸중 어린 나무부터 양분을 먹는다 -> 같은 칸에 여러개의 나무가 있다면, '정렬'해야한다.
3. 나무의 나이가 5의 배수일때, 인접한 칸에 나이1의 나무를 생성한다 -> 8방향 방향데이터로, bfs에서 다음 정점을 탐색할때처럼 비슷하게 구현하면 된다.
시뮬레이션이 끝난 후, 구해야하는 답은 모든 벡터[i][j]의 사이즈의 합이다.
<소스코드>
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105#include<stdio.h>#include<vector>#include<algorithm>using namespace std;int n, m, k;int a[11][11];//겨울마다 추가되는 양분int food[11][11];//양분vector<int>tree[11][11];vector<int>dead[11][11];vector<int>temp;int dy[8] = { -1,-1,0,1,1,1,0,-1 };int dx[8] = { 0,1,1,1,0,-1,-1,-1 };//12시부터 시계방향, 총 8방향int main(void) {int i, j, x, y;scanf("%d %d %d", &n, &m, &k);for (i = 1; i <= n; i++) {for (j = 1; j <= n; j++) {scanf("%d", &a[i][j]);food[i][j] = 5;//초기 양분은 5}}for (i = 1; i <= m; i++) {int A,B,C;scanf("%d %d %d", &A, &B, &C);// 행, 열, 나이tree[A][B].push_back(C);}while (k--) {//봄for (i = 1; i <= n; i++) {for (j = 1; j <= n; j++) {if (tree[i][j].size() == 0)continue;sort(tree[i][j].begin(), tree[i][j].end());//어린 나무부터for (x = 0; x < tree[i][j].size(); x++) {if (food[i][j] >= tree[i][j][x]) {//충분한 양분이 있다면food[i][j] -= tree[i][j][x];//나이만큼 양분을 먹고temp.push_back(tree[i][j][x] + 1);//증가된 나이를 저장한다}else { //양분이 없다면dead[i][j].push_back(tree[i][j][x]);//죽은 나무 목록에 나이를 넣는다}}tree[i][j].clear();for (x = 0; x < temp.size(); x++) {tree[i][j].push_back(temp[x]);}temp.clear();}}//여름for (i = 1; i <= n; i++) {for (j = 1; j <= n; j++) {if (dead[i][j].size() == 0)continue;for (x = 0; x < dead[i][j].size(); x++) {food[i][j] += (dead[i][j][x] / 2);//양분을 (죽은 나무 나이)/2 만큼 증가}dead[i][j].clear();}}//가을for (i = 1; i <= n; i++) {for (j = 1; j <= n; j++) {if (tree[i][j].size() == 0)continue;for (x = 0; x < tree[i][j].size(); x++) {if (tree[i][j][x] % 5 == 0) {//나이가 5의 배수일때for (y = 0; y < 8; y++) {//8방향으로int ty, tx;ty = i + dy[y];tx = j + dx[y];if (ty <= 0 || tx <= 0 || ty > n || tx > n)continue;//땅을 벗어나면 자라지 않는다tree[ty][tx].push_back(1);//나이가 1인 나무를 생성한다.}}}}}//겨울for (i = 1; i <= n; i++) {for (j = 1; j <= n; j++) {food[i][j] += a[i][j];//양분을 추가}}/*printf("-------------------\n");for (i = 1; i <= n; i++) {for (j = 1; j <= n; j++) {for (x = 0; x < tree[i][j].size(); x++)printf("[%d][%d] : %d", i,j,tree[i][j][x]);}printf("\n");}printf("-------------------\n");*/}//k년이 지난 후int answer = 0;for (i = 1; i <= n; i++) {for (j = 1; j <= n; j++) {answer += tree[i][j].size();//printf("<%d>", answer);}}printf("%d", answer);return 0;}cs 'BOJ' 카테고리의 다른 글
[1328] 고층 빌딩 (0) 2021.09.01 [1715] 카드 정렬하기 (0) 2021.09.01 [5615] 아파트 임대 (0) 2021.09.01 [1259] 팰린드롬수 (0) 2021.09.01 [10942] 팰린드롬? (0) 2021.09.01