큐, 구현, 시뮬레이션
spring,summer,autumn, winter 를 각각 처리해 주고
문제에 있는 그대로를 구현하면 되므로 전체적으로는 45분 만에 끝냈다.
하지만 제출을 해도 40% 정도에서 시간 초과가 발생했고
정렬을 하는 부분에서 시간초과가 났을 것으로 예상은 했으나
이를 어떻게 개선해야할지를 떠올리지 못해서 질문게시판을 참고했다.
참고한 내용은 나이가 1인 나무들은 정렬할 필요가 없으므로, 따로 처리해 주는 것이다. 그렇게 하면 정렬의 범위를 크게 줄일 수 있다.
[1,2,3] - Spring
[4] - Summer
[5] - Autumn
[6] - Winter
import java.util.*;
import java.io.*;
public class Main{
static int land[][];
static int plus[][];
static LinkedList<Integer[]> tree=new LinkedList<>();
static LinkedList<Integer[]> deadTree=new LinkedList<>();
static Queue <Integer[]> queue=new LinkedList<>();
static int cnt = 0;
static int dy[] = {-1,-1,0,1,1,1,0,-1};
static int dx[] = {0,1,1,1,0,-1,-1,-1};
public static void main(String[] args) throws IOException{
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
StringBuilder sb=new StringBuilder();
StringTokenizer st;
st=new StringTokenizer(br.readLine());
int N=Integer.parseInt(st.nextToken());
int M=Integer.parseInt(st.nextToken());
int K=Integer.parseInt(st.nextToken());
land=new int[N+1][N+1];
plus=new int[N+1][N+1];
for(int i=1;i<land.length;i++) {
st=new StringTokenizer(br.readLine());
for(int j=1;j<land[0].length;j++) {
plus[i][j] = Integer.parseInt(st.nextToken());
land[i][j] = 5;
}
}
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 z=Integer.parseInt(st.nextToken());
tree.add(new Integer[] {x,y,z});
}
for(int i=0;i<K;i++) {
//나무가 없다면 , 멈춘다
if(tree.size()==0&&queue.size()==0) break;
Spring();
Summer();
Autumn();
Winter();
}
//나무의 개수를 출력
System.out.println(tree.size()+queue.size());
}
public static void Spring() {
//나무들을 정렬한다. 나이 수가 적은 순서대로
Collections.sort(tree,new Comparator<>() {
@Override
public int compare(Integer[] n1,Integer[] n2) {
if(n1[2]>n2[2])
return 1;
else if(n1[2]==n2[2])
return 0;
else
return -1;
}
});
//임시저장할 곳
LinkedList<Integer[]> temp=new LinkedList<>();
//나이가 1인 나무들은 정렬할 필요가 없으니 따로 처리.
//땅의 양분이 1 이상이면, 나이가 2가 됨
while(!queue.isEmpty()) {
Integer poll[]=queue.poll();
int nowY=poll[0];
int nowX=poll[1];
if(land[nowY][nowX]>0) {
land[nowY][nowX]-=1;
temp.add(new Integer[] {nowY,nowX,2});
}
}
while(!tree.isEmpty()) {
Integer poll[]=tree.pollFirst();
int nowY=poll[0];
int nowX=poll[1];
int age=poll[2];
//양분이 나이 이상이면, 나이 1증가, 양분 감소
if(land[nowY][nowX]>=age) {
land[nowY][nowX]-=age;
temp.add(new Integer[] {nowY,nowX,age+1});
}
//아니라면 죽은 나무에 추가
else {
deadTree.add(new Integer[] {nowY,nowX,age});
}
}
//임시저장한 것을 다시나무에 저장
while(!temp.isEmpty()) {
tree.add(temp.removeFirst());
}
}
public static void Summer() {
//죽은 나무의 나이/2 만큼 양분 증가
while(!deadTree.isEmpty()) {
Integer temp[]=deadTree.pollFirst();
int nowY=temp[0];
int nowX=temp[1];
int age=temp[2];
land[nowY][nowX] += (age/2);
}
}
public static void Autumn() {
LinkedList<Integer[]> temp=new LinkedList<>();
while(!tree.isEmpty()) {
Integer poll[]= tree.pollFirst();
int nowY=poll[0];
int nowX=poll[1];
int age = poll[2];
//나이가 5의 배수라면
if(age%5==0) {
for(int i=0;i<dx.length;i++) {
int nextY=nowY+dy[i];
int nextX=nowX+dx[i];
if(nextY<1||nextX<1||nextY>=land.length||nextX>=land[0].length)
continue;
//나이가 1인 나무에 추가
queue.add(new Integer[] {nextY,nextX});
}
}//
temp.add(poll);
}
while(!temp.isEmpty()) {
tree.add(temp.pollFirst());
}
}
public static void Winter() {
//양분 증가
for(int i=1;i<plus.length;i++) {
for(int j=1;j<plus[0].length;j++) {
land[i][j] += plus[i][j];
}
}
}
}
계속 시간초과가 나서 질문게시판을 참고했고,
그 결과 1316ms 로 정답을 받았다.
그 후 인터넷의 다른 사람 풀이를 제출했을 때 860ms 가 나왔다.
이 문제들에 대해서 나무들의 값을 정렬하지 않고도 풀 수 있다는 글을 봤는데, 아직까지는 어떻게 그렇게 한 것인지 모르겠다. 그에 대해서 추가로 공부해 볼 예정이다.
하루에 백준 1문제 이상 푸는 것을 목표로 하고있다.
https://solved.ac/profile/anwlro0212