[BOJ 16235] 나무재테크

업데이트:

문제

  • BOJ 16235
  • 문제의 저작권은 Baekjoon Online Judge에 있습니다.

접근방식

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.StringTokenizer;

//나무제테크
public class Main {

	static int N; //땅 크기
	static int M; //나무 수
	static int K; //년
	static int[][] map; //땅
	static int[][] A; //추가되는 양분 양
	static List<Tree> trees; //전체 나무 정보
	static List<Tree> alive;
	static List<Tree> deaths; //죽은 나무
	static int[] di = {-1, -1, -1, 0, 0, 1, 1, 1};
	static int[] dj = {-1, 0, 1, -1, 1, -1, 0, 1};

	public static void main(String[] args) throws NumberFormatException, 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());

		A = new int[N+1][N+1];
		map = new int[N+1][N+1];
		trees = new ArrayList<>();

		for(int i=1; i<=N; i++) {
			st = new StringTokenizer(br.readLine());
			for(int j=1; j<=N; j++) {
				A[i][j] = Integer.parseInt(st.nextToken());
				map[i][j] = 5; //처음 모든 양분 5
			}
		}//input 추가 양분

		for(int i=0; i<M; i++) {
			st = new StringTokenizer(br.readLine());
			int x = Integer.parseInt(st.nextToken());
			int y = Integer.parseInt(st.nextToken());
			int age = Integer.parseInt(st.nextToken());
			trees.add(new Tree(x, y, age));
		}//input 나무


		//사계절 시작
		for(int i=0; i<K; i++) {
			alive = new ArrayList<>();
			deaths = new ArrayList<>();
			spring(); //봄
			summer(); //여름
			autumn(); //가을
			winter(); //겨울
		}

		System.out.println(trees.size());
	}

	private static void winter() { //겨울

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

	private static void autumn() { //가을
		trees.clear();
		for(Tree tree : alive) {
			if(tree.age % 5 == 0) {
				for(int d=0; d<8; d++) {
					int nx = tree.x + di[d];
					int ny = tree.y + dj[d];

					if(nx>=1 && nx<=N && ny>=1 && ny <= N) {
						trees.add(new Tree(nx, ny, 1));
					}
				}
			}
		}
		trees.addAll(alive); //살아있는 나무만 넣기
	}

	private static void summer() { //여름
		for(int i=0; i<deaths.size(); i++) { //죽은 나무/2만큼 양분 추가
			Tree death = deaths.get(i);
			map[death.x][death.y] += death.age / 2;
		}
	}

	private static void spring() { //봄
		Collections.sort(trees); //나이어린나무 오름차순
		int size = trees.size();
		for(Tree tree : trees) {
			if(map[tree.x][tree.y] >= tree.age) { //나이만큼 먹을 수 있다면
				//양분먹고 나이 1증가
				map[tree.x][tree.y] -= tree.age;
				tree.age++;
				alive.add(new Tree(tree.x, tree.y, tree.age));
			}else { //양분이 부족해 못 먹는다면 죽음
				deaths.add(tree);
			}
		}
	}

	static class Tree implements Comparable<Tree>{
		int x; //좌표
		int y;
		int age; //나무 나이

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

		@Override
		public int compareTo(Tree o) {
			return this.age - o.age;
		}
	}
}