알고리즘
bj16235(나무 제테크)-구현
쥐4
2025. 4. 22. 16:33
https://www.acmicpc.net/problem/16235
이 문제는 개극혐이다.
그냥 구현이다. 클래스를 나누고 메서드를 나누면 쉽게 풀린다.
다만, 시간이 엄청 오래걸린다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
public class Main {
/**
* 봄 => 나이만큼 양분먹음, 나이 1증가, 여러개의 나무 가능, 양분못먹으면 죽음
* => 나이대로 정렬이 필요 특정 시점부터 여름 적용 필요
* 여름=> 죽은 나무 양분됨. 죽은나무 나이/2가 양분으로 추가됨
* => 봄에서 한 번에 처리
* 가을=> 5배수 나무일 시 번식(8개)
* => 봄에서 따로 나무 모아두기
* => 다 처리 후 번식
* 겨울=> 땅에 양분 추가
* => 따로 처리
*
* N => N*N
* M => 나무 갯수
* K => 년 수
*
* 10 * 10 * 4
*/
static int N, M, K;
static int[][] foods;
static Ground[][] grounds;
static StringTokenizer stringTokenizer;
static BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
public static void main(String[] args) throws IOException {
initialize();
System.out.println(solve());
}
private static int solve() {
for(int k = 0; k < K; k++){
Queue<int[]> totalBreedTrees = new ArrayDeque<>();
for(int y = 0; y < N; y++){
for(int x = 0; x < N; x++){
Queue<int[]> breedTrees = grounds[y][x].process(grounds, N);
totalBreedTrees.addAll(breedTrees);
}
}
grounds[0][0].breedTree(grounds, N, totalBreedTrees);
for(int y = 0; y < N; y++){
for(int x = 0; x < N; x++){
grounds[y][x].food += foods[y][x];
}
}
}
int answer = 0;
for(int y = 0 ; y < N; y++){
for(int x = 0; x < N; x++){
answer += grounds[y][x].getTreeCnt();
}
}
return answer;
}
private static void initialize() throws IOException {
stringTokenizer = new StringTokenizer(bufferedReader.readLine());
N = Integer.parseInt(stringTokenizer.nextToken());
M = Integer.parseInt(stringTokenizer.nextToken());
K = Integer.parseInt(stringTokenizer.nextToken());
foods = new int[N][N];
grounds = new Ground[N][N];
for(int y = 0; y < N; y++){
stringTokenizer = new StringTokenizer(bufferedReader.readLine());
for(int x = 0; x < N; x++){
grounds[y][x] = new Ground();
grounds[y][x].food = 5;
foods[y][x] = Integer.parseInt(stringTokenizer.nextToken());
}
}
for(int i = 0; i < M; i++){
stringTokenizer = new StringTokenizer(bufferedReader.readLine());
int y = Integer.parseInt(stringTokenizer.nextToken())-1;
int x = Integer.parseInt(stringTokenizer.nextToken())-1;
grounds[y][x].trees.add(new int[]{y,x,Integer.parseInt(stringTokenizer.nextToken())});
}
}
}
class Ground{
PriorityQueue<int[]> trees = new PriorityQueue<>((o1, o2) -> o1[2]-o2[2]);
int food;
public Queue<int[]> process(Ground[][] map, int N){
Queue<int[]> liveTree = new ArrayDeque<>();
Queue<int[]> breedTree = new ArrayDeque<>();
while(true){
if(!trees.isEmpty() && food - trees.peek()[2] >= 0){
int[] tree = trees.poll();
food -= tree[2];
tree[2]++;
liveTree.add(tree);
if(tree[2] % 5 == 0){
breedTree.add(tree);
}
continue;
}
break;
}
plusFood();
while(!liveTree.isEmpty()){
trees.add(liveTree.poll());
}
return breedTree;
}
public void breedTree(Ground[][] map, int N, Queue<int[]> breedTree) {
int[] dy = {1,0,-1,0,1,-1,1,-1};
int[] dx = {0,1,0,-1,1,-1,-1,1};
while(!breedTree.isEmpty()){
int[] temp = breedTree.poll();
for(int i = 0; i < 8; i++){
int ny = temp[0] + dy[i];
int nx = temp[1] + dx[i];
if(ny < 0 || ny >= N || nx < 0 || nx >= N)continue;
map[ny][nx].trees.add(new int[]{ny, nx, 1});
}
}
}
public void plusFood(){
while(!trees.isEmpty()){
int[] temp = trees.poll();
food += temp[2] / 2;
}
}
public int getTreeCnt(){
return trees.size();
}
}