BOJ 20056번 마법사 상어와 파이어볼 자바(java) 풀이
문제 정리
- NxN 크기의 격자
- 파이어볼 M개
- i번 파이어볼의 위치(r, c), 질량 m, 방향 d, 속력 s
- 격자의 번호는 1~N
- 1번 행은 N번과 연결/ 1번 열은 N번 열과 연결
- 파이어볼은 8개의 방향을 가짐
- 파이어볼은 다음과 같이 이동한다.
7.1 자신의 방향 d로 속력 s 만큼 이동
7.2 이동이 끝난 뒤, 2개 이상의 파이어볼이 같은 칸에 있으면 다음 일이 일어남
- 같은 칸의 파이어볼은 모두 하나로 합쳐짐
- 파이어볼이 4개로 나누어짐
- 나누어진 파이어볼의 질량, 속력, 방향이 바뀜
- 질량이 0인 파이어볼은 소멸
- K번 명령 후, 남아있는 파이어볼의 질량의 합 구하기
전체 로직
문제에 주어진 그대로 잘 구현하기만 하면 되는 시뮬레이션 문제입니다.
이를 쉽게 풀기 위해서 NxN 격자를 ArrayList 2차원 배열로 구현하였습니다.(ArrayList<>[][] map)
- arraylist 2차원 배열을 초기화한다.
- 값을 입력 받는다. 이때 초기 질량의 합을 구해놓는다.
- 해당 위치의 arraylist에 FireBall 객체를 추가한다.
- 이동하고 합쳐지는 것을 k번 반복한다.
- 전체 질량을 담고 있는 tot를 출력한다.
파이어볼 이동 구현
정리 7.1을 구현합니다.
- 맵을 순회하며 그 위치의 list에 원소의 개수가 0이 아닌지 탐색합니다. 즉 무언가가 있다면 이동시킵니다.
- 담겨 있는 파이어볼 개수만큼 for문을 반복합니다. dx, dy는 방향으로 속도만큼 이동 시킨 후의 위치 입니다.
- 이때 N으로 나눈 나머지를 구하는 이유는 10만큼 이동해야하고 N이 3이라면 결국 1만큼 이동한것과 같기 때문입니다.
- 이동 시킨 위치가 N을 넘거나 1보다 작은 경우를 처리합니다.(5번 조건 구현)
- 바로 이동시키면 for문을 돌면서 또 이동시키게 되므로 tempList에 담았다가 나중에 한번에 이동시키도록 합니다. 그리고 이동했으므로 현재 list에서 삭제시킵니다.
- tempList에 있는 파이어볼들을 이동 시킵니다.
파이어볼 합체
- 2중 for문을 돌며 2개 이상인게 있는지 확인합니다.
- 2개 이상이라면 파이어볼의 질량과 속도를 모두 합칩니다. 이때 방향을 정하기 위해 모두 짝/홀 인지 검사합니다.
- 전체 질량에서 합쳐진 파이어볼들의 질량을 빼줍니다.
- 새로 만들어진 파이어볼의 질량, 속력을 구합니다.
- 현재 위치에 있는 파이어볼을 모두 제거합니다.(합쳐지기 때문)
- 질량이 0이 아니라면 소멸되지 않고 4개로 나누어집니다.
- 모두 홀수거나 짝수인 경우 0,2,4,6 방향의 파이어볼 4개를 생성 / 그렇지 않은 경우 1,3,5,7 파이어볼 4개를 생성해줍니다.
백준 20056번 마법사 상어와 파이어볼 자바 코드