나무 재테크 - LinkedList, Iterator, addAll(0,List)로 풀기
(x,y) 위치에서 나무의 나이 값으로 양분이 증감되고, 나무가 생기고 없어진다.
따라서 (x,y)에 대해 "나무"를 어떻게 저장할지 고민이 많았다.
나무 클래스를 생성하고, 나무들 정보를 리스트로 저장하는 방법
Map<key, value> => key : (x,y), value : 나무의 나이만을 저장한 int[ ]
1번 방법은 (x,y) 위치에 대해서 아래 그림처럼 접근했었다.

그러다가 (x,y)를 key로 잡고, key(x,y)에 대해 나무들을 가지고 연산(수정,추가,삭제)하는 것이 구현에 용이하다고 생각해서 Map으로 구현했다. 2중 for문으로 (x,y)에 있는 나무들을 연산(수정,추가,삭제). Map을 잘 사용해보지 않았어서 그런지 NullPointerException이 발생하는데 해결핮지 못했다.
정답 솔루션
자료 구조 트리 클래스 생성, 트리 정보들을 리스트로 저장✅ =>트리 클래스 정의할 때, 한가지 정보를 더 저장한다! 나무의 생사를 저장하는 boolean 변수도 속성으로 함께 저장한다!
알고리즘
전체 연산(봄, 여름, 가을, 겨울) 반복 조건 : K년 이기 때문에 K번 반복한다.
(x,y)와 트리 자료구조 어떻게 풀어내었는가?🧐⭐️⭐️⭐️⭐️⭐️ for-each문으로 나무들을 저장한 list로 반복문 구현!!
for(int k=0;k<K;k++){
//봄
for(Tree t:Trees){...}
//여름
//가을
//겨울
}
🍃봄 : 나무의 나이만큼 양분 먹고, 그럴 수 없다면 나무 죽는다. 나무 죽는 것은 속성값 alive를 true에서 false로 바꿔줌으로써 구현 가능하다!
⛱여름 : 트리 list에서 봄에 죽은 나무 (tree.alive == false)인 나무 찾아서 해당 트리의 위치(tree.x,tree.y)에 있는 양분 양을 나이/2만큼 증가시키고, 트리 list에서 삭제한다.
Iterator 인터페이스 반복자 사용하는 이유 => java의 내부구조상, for-each문으로 반복하는 중에 리스트를 조작(추가/수정/삭제)할 경우 ConcurrentModificationException 가 발생하거나 순회가 잘못될 수 있다고 한다!!! "for-each로 List 순회 중에는 node를 삭제할 수 없습니다." 그렇기 때문에 for-each가 아닌 다른 방법으로 반복문을 구현해야한다. 이때,Iterator 라는 인터페이스 반복자를 사용함으로써 반복문을 돌면서 리스트를 수정할 수 있다. ① 인터페이스 구현 : Iterator<Object> it = LinkedList_name.Iterator(); ② 반복문 구현 : hasNext()를 사용해서 for문 또는 while문 구현. hasNext()는 다음 데이터가 있으면 true를, 없으면 false를 반환한다. ex) for(Itreator<Tree> it = Trees.Iterator();it.hasNext) while(it.hasNext)
🍁가을 : 나무 나이가 5의 배수이면 인접 8개 위칭에 나이가 1인 나무 생긴다. =>그냥 델타어레이로 인접 노드 좌표(nx,ny) 구해서 해당 위치의 트리 인스턴스 생성, 트리 list에 추가하면 된다. 주의할 점! 여름의 경우와 마찬가지로, for-each문을 도는 중에 list 수정이 불가하므로, 새로 생겨나는 트리를 저장할 list를 따로 생성한 다음, 원래의 트리 list에 합친다! list에 list를 합칠 때 addAll() 메서드를 사용함으로써 나이가 1인 나무들은 자동으로 앞에 저장하고, 정렬할 필요 없다. =>🧐 어 그럼 기존의 나무들 순서는 어떻게 되있는 거지? =>문제에서 초기 입력으로 주어지는 나무들은 전부 모두 다른 위치에 있다고 되어있기 때문에 같은 위치에 나무 여러개 존재해서 나이순대로 정렬할 걱정은 안 해도 된다.
☃️겨울 : 로봇이 입력값으로 주어지는 양분 양만큼 양분 공급한다.(EASY) => 2중 for문으로 현재 양분 값 F [ i ][ j ] 에 입력값 A [ i ][ j ] 더한다.
Last updated
Was this helpful?