새소식

알고리즘 문제풀이/BOJ

[시뮬레이션] 백준 20056번 마법사 상어와 파이어볼 :: 삼성 sw 역량 테스트 기출 (java)

  • -

BOJ 20056번 마법사 상어와 파이어볼 자바(java) 풀이

 

문제 정리

  1. NxN 크기의 격자
  2. 파이어볼 M개
  3. i번 파이어볼의 위치(r, c), 질량 m, 방향 d, 속력 s
  4. 격자의 번호는 1~N
  5. 1번 행은 N번과 연결/ 1번 열은 N번 열과 연결
  6. 파이어볼은 8개의 방향을 가짐
  7. 파이어볼은 다음과 같이 이동한다.
    7.1 자신의 방향 d로 속력 s 만큼 이동
    7.2 이동이 끝난 뒤, 2개 이상의 파이어볼이 같은 칸에 있으면 다음 일이 일어남
     - 같은 칸의 파이어볼은 모두 하나로 합쳐짐
     - 파이어볼이 4개로 나누어짐
     - 나누어진 파이어볼의 질량, 속력, 방향이 바뀜
     - 질량이 0인 파이어볼은 소멸
  8. K번 명령 후, 남아있는 파이어볼의 질량의 합 구하기


전체 로직

문제에 주어진 그대로 잘 구현하기만 하면 되는 시뮬레이션 문제입니다.
이를 쉽게 풀기 위해서 NxN 격자를 ArrayList 2차원 배열로 구현하였습니다.(ArrayList<>[][] map)

  1. arraylist 2차원 배열을 초기화한다.
  2. 값을 입력 받는다. 이때 초기 질량의 합을 구해놓는다.
  3. 해당 위치의 arraylist에 FireBall 객체를 추가한다.
  4. 이동하고 합쳐지는 것을 k번 반복한다.
  5. 전체 질량을 담고 있는 tot를 출력한다.


파이어볼 이동 구현

정리 7.1을 구현합니다.

  1. 맵을 순회하며 그 위치의 list에 원소의 개수가 0이 아닌지 탐색합니다. 즉 무언가가 있다면 이동시킵니다.
  2. 담겨 있는 파이어볼 개수만큼 for문을 반복합니다. dx, dy는 방향으로 속도만큼 이동 시킨 후의 위치 입니다.
  • 이때 N으로 나눈 나머지를 구하는 이유는 10만큼 이동해야하고 N이 3이라면 결국 1만큼 이동한것과 같기 때문입니다.
  1. 이동 시킨 위치가 N을 넘거나 1보다 작은 경우를 처리합니다.(5번 조건 구현)
  2. 바로 이동시키면 for문을 돌면서 또 이동시키게 되므로 tempList에 담았다가 나중에 한번에 이동시키도록 합니다. 그리고 이동했으므로 현재 list에서 삭제시킵니다.
  3. tempList에 있는 파이어볼들을 이동 시킵니다.


파이어볼 합체

  1. 2중 for문을 돌며 2개 이상인게 있는지 확인합니다.
  2. 2개 이상이라면 파이어볼의 질량과 속도를 모두 합칩니다. 이때 방향을 정하기 위해 모두 짝/홀 인지 검사합니다.
  3. 전체 질량에서 합쳐진 파이어볼들의 질량을 빼줍니다.
  4. 새로 만들어진 파이어볼의 질량, 속력을 구합니다.
  5. 현재 위치에 있는 파이어볼을 모두 제거합니다.(합쳐지기 때문)
  6. 질량이 0이 아니라면 소멸되지 않고 4개로 나누어집니다.
  7. 모두 홀수거나 짝수인 경우 0,2,4,6 방향의 파이어볼 4개를 생성 / 그렇지 않은 경우 1,3,5,7 파이어볼 4개를 생성해줍니다.

백준 20056번 마법사 상어와 파이어볼 자바 코드

 

Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.