나무 재테크 - LinkedList, Iterator, addAll(0,List)로 풀기
Last updated
Last updated
(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로 반복문 구현!!
🍃봄 : 나무의 나이만큼 양분 먹고, 그럴 수 없다면 나무 죽는다. 나무 죽는 것은 속성값 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 ] 더한다.