본문 바로가기
문제풀이/백준

[JAVA] BOJ 백준 16235번 - 나무 재테크

by 그적 2024. 1. 2.

목차

  • 문제
  • 내가 푼 방법
  • 자바 코드
  • 결과 및 회고

1. 문제

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

 

16235번: 나무 재테크

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

www.acmicpc.net


2. 내가 푼 방법

열심히 실수하지 않고 구현해주면 쉽게 풀리는 문제이다.

 

상도가 키우는 나무를 우선순위 큐에 담아, 봄에 나무 나이가 어린 나무부터 양분을 먹을 수 있도록 했다.

또한 point 배열은 땅의 양분의 기준이 되고, diePoint 배열은 봄, 여름에 필요한 죽은 나무들의 양분을, addPoint 배열은 봄에 추가하는 양분을 저장해두었다.


3. 자바 코드

깃허브 풀이 주소 : https://github.com/geujeog/BOJ/blob/main/B16235.java

import java.util.*;
import java.io.*;

class Main {
    static int N, M, K;
    static int[][] point;
    static int[][] addPoint;
    static PriorityQueue<Tuple> trees;
    static int[][] diePoint;
    static int result;

    public static void main(String[] args) throws IOException {
        input();
        solution();
        output();
    }

    public static void solution() {
        for (int i = 0; i < K; i++) {
            spring();
            summer();
            fall();
            winter();
        }
    }

    public static void winter() {
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                point[i][j] += addPoint[i][j];
            }
        }

        result = trees.size();
    }

    public static void fall() {
        PriorityQueue<Tuple> newTrees = new PriorityQueue<>();

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

        while (!trees.isEmpty()) {
            Tuple t = trees.poll();
            int x = t.x;
            int y = t.y;
            int age = t.age;

            newTrees.add(t);

            if (age % 5 == 0) {
                for (int i = 0; i < 8; i++) {
                    int nx = x + dx[i];
                    int ny = y + dy[i];

                    if (nx < 0 || ny < 0 || nx >= N || ny >= N) continue;
                    newTrees.add(new Tuple(nx, ny, 1));
                }
            }
        }

        trees.addAll(newTrees);
    }

    public static void summer() {
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                point[i][j] += diePoint[i][j];
            }
        }
    }

    public static void spring() {
        PriorityQueue<Tuple> newTrees = new PriorityQueue<>();
        diePoint = new int[N][N];

        while (!trees.isEmpty()) {
            Tuple t = trees.poll();
            int x = t.x;
            int y = t.y;
            int age = t.age;

            if (point[x][y] >= age) {
                point[x][y] -= age;
                newTrees.add(new Tuple(x, y, age+1));
            }
            else {
                diePoint[x][y] += (int) age / 2;
            }
        }

        trees.addAll(newTrees);
    }

    public static class Tuple implements Comparable<Tuple> {
        int x;
        int y;
        int age;

        public Tuple (int x, int y, int age) {
            this.x = x;
            this.y = y;
            this.age = age;
        }

        @Override
        public int compareTo(Tuple t) {
            return this.age - t.age;
        }
    }

    public static void output() throws IOException {
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

        bw.write(result+"");

        bw.flush();
        bw.close();
    }

    public static void input() throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        StringTokenizer st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());
        K = Integer.parseInt(st.nextToken());
        point = new int[N][N];
        addPoint = new int[N][N];
        trees = new PriorityQueue<>();

        for (int i = 0; i < N; i++) {
            st = new StringTokenizer(br.readLine());

            for (int j = 0; j < N; j++) {
                point[i][j] = 5;
                addPoint[i][j] = Integer.parseInt(st.nextToken());
            }
        }

        for (int i = 0; i < M; i++) {
            st = new StringTokenizer(br.readLine());

            int x = Integer.parseInt(st.nextToken()) - 1;
            int y = Integer.parseInt(st.nextToken()) - 1;
            int age = Integer.parseInt(st.nextToken());

            trees.add(new Tuple(x, y, age));
        }

        br.close();
    }
}

4. 결과 및 회고

구현 문제는 함수를 잘 쪼개가면서 실수하지 않는 게 중요한 것 같다.

댓글