[코테] 격자 안에서 터지고 떨어지는 경우

시뮬레이션


격자 안에서 터지고 떨어지는 경우

  • 특정 규칙에 의해 폭탄이 터지게 되고, 그 이후에 중력이 작용하여 위에 떠있는 폭탄들이 아래로 떨어지는 작업
  • 2차원 격자인 경우 : 새로운 temp 배열을 이용한다.
    1. temp 배열을 새로 만들어준다.
    2. 아래에서 위로 올라오면서, 비어있지 않을 때만 temp에 넣어준다.
    image
    • col열의 가장 밑인 n-1부터 0까지 row값을 감소시키면서 temp에 채운다.
      1. temp 배열의 값을 기존 배열로 옮겨준다.
  • 1차원 배열인 경우 : 주어진 모양을 반시계방향으로 90도 회전하여 생각한다.
    1. temp 배열을 새로 만들어준다.
      • end_of_temp_array 변수의 초기값은 0으로 설정한다.
    2. 왼쪽에서 오른쪽으로 가면서, 비어있지 않을 때만 temp에 넣어준다.
    image
    • 0부터 시작해서 n-1 인덱스까지 비어 있지 않은 경우, temp에 하나씩 옮기면서 end_of_tem_array 변수를 1씩 증가시킨다.
      1. temp 배열의 값을 기존 배열로 옮겨준다.


문제

n개의 층으로 이루어진 1차원 젠가의 상태가 주어집니다. 각 층마다 1개의 블럭이 놓여져 있고, 각 블럭에는 1이상 100 이하의 숫자가 하나씩 적혀있습니다.

image

이 때 2번에 걸쳐 특정 구간의 블럭들을 빼는 작업을 진행하려 합니다.

처음에 위에서부터 2번째 블럭에서 4번째 블럭까지 블럭을 빼게 된다면, 남은 블럭은 중력에 의해 떨어지게 되어 다음과 같이 블럭이 남게 됩니다.

image

그 다음에는 2번째 블럭만 빼게 된다면, 다음과 같이 블럭이 남게 됩니다. image

특정 구간의 블럭을 두 번 빼는 과정을 거친 이후의 결과를 출력하는 프로그램을 작성해보세요.

입력 형식

첫 번째 줄에는 처음 놓여있는 블럭의 수를 의미하는 n이 주어집니다.

두 번째 줄부터는 n개의 줄에 걸쳐 맨 위에서부터 맨 아래까지 순서대로 각 층에 놓여있는 블럭에 적혀있는 숫자가 주어집니다.

그 다음 줄에는 첫 번째로 제거할 블럭의 정보를 나타내는 (s1, e1) 값이 공백을 사이에 두고 주어집니다. (s1 ≤ e1) 이는 위에서부터 s1번째 부터 e1번째까지의 블럭을 뺀다는 것을 의미합니다.

마지막 줄에는 두 번째로 제거할 블럭의 정보를 나타내는 (s2, e2) 값이 공백을 사이에 두고 주어집니다. (s2 ≤ e2) 이는 위에서부터 s2번째 부터 e2번째까지의 블럭을 뺀다는 것을 의미합니다.

해당 구간에 놓인 블럭을 빼는 것이 불가능한 입력은 주어지지 않는다고 가정해도 좋습니다.

  • 2 ≤ n ≤ 100

출력 형식

두 번의 블록 빼기 작업을 진행한 이후의 결과를 출력합니다.

첫 번째 줄에는 남은 블록의 개수를 출력합니다.

그 다음 번째 줄 부터는 한 줄에 하나씩 위에서부터 남은 블록에 적힌 숫자들을 순서대로 출력합니다.

입출력 예제

입력:
 6
  1
  2
  3
  1
  1
  5
  2 4
  2 2
출력:
  2
  1
  5

✔️ 문제 풀이

1차원 젠가 안에서 진행되는 문제니까 1차원 배열의 경우를 적용해서 문제를 해결하였다.

1차원 젠가가 주워졌을 때 s1부터 e1까지의 구간과 s2부터 e2까지 구간의 블럭을 빼야하기 때문에 cut 함수를 정의하였다. 주어진 s1과 e1 구간 이외의 블럭만 temp에 순서대로 옮겨주고, 옮길 때마다 temp_end_of_array 변수의 값을 1씩 증가해 배열의 길이를 알 수 있도록 하였다. 함수의 마지막에는 temp 배열을 다시 원래 배열로 옮겨준다.
이 과정을 2번 반복하여 마지막에 남은 블럭을 순서대로 출력한다.

  n = int(input())
  arr = [
      int(input())
      for _ in range(n)
  ]

  end_of_array = n

  def cut(s, e):
      temp = []
      temp_end_of_array = 0

      global end_of_array 

      for i in range(end_of_array):
          if i < s or i > e:
              temp.append(arr[i])
              temp_end_of_array += 1
      end_of_array = temp_end_of_array

      for i in range(end_of_array):
          arr[i] = temp[i]

  for _ in range(2):
      s, e = tuple(map(int, input().split()))
      cut(s-1, e-1) # 입력 : s1번째부터 e1번째까지의 블럭을 뺀다

  print(end_of_array)
  for i in range(end_of_array):
      print(arr[i])
  • 개선할 부분
    temp_end_of_array 변수를 따로 사용하지 않고 len함수를 사용해서 배열의 길이를 측정하는 게 코드가 더 깔끔하다.
    end_of_array = len(temp)

cut 함수에서 end_of_array 변수 값을 변경하고 이후에 사용해야 하기 때문에 global end_of_array와 같이 전역 변수로 선언해주어야 한다. 이 부분을 빼먹어서 오류가 발생함



문제출처: 코드트리의 문제 및 풀이를 정리한 내용입니다.

https://www.codetree.ai/missions/2/problems/jenga-1d?&utm_source=clipboard&utm_medium=text


© 2021. All rights reserved.

yaejinkong의 블로그