파이썬 μ•Œκ³ λ¦¬μ¦˜

[μ΄μ½”ν…Œ Ch12-10] μžλ¬Όμ‡ μ™€ μ—΄μ‡  (κ΅¬ν˜„)

은진 2022. 3. 15. 19:50

πŸ‘©πŸ»β€πŸ’»λ¬Έμ œμ„€λͺ…

[μ΄μ½”ν…Œ Ch12-10] μžλ¬Όμ‡ μ™€ μ—΄μ‡  (κ΅¬ν˜„)
μ΄μ½”ν…Œ

✍️Idea Sketch

문제 μš”μ•½

μžλ¬Όμ‡ μ™€ νšŒμ „, 이동이 κ°€λŠ₯ν•œ μ—΄μ‡ κ°€ μžˆλ‹€.
λͺ©ν‘œ : μžλ¬Όμ‡ μ˜ λͺ¨λ“  μ˜μ—­μ„ 1둜 μ±„μš°κΈ° = μžλ¬Όμ‡ μ˜ λͺ¨λ“  ν™ˆμ„ μ±„μš°κΈ°

μ—΄μ‡  μ›€μ§μž„ μ’…λ₯˜

  1. νšŒμ „ : μ‹œκ³„λ°©ν–₯ 90도 (90도 ν•¨μˆ˜ ν•˜λ‚˜ 만으둜 180도, 270도 λ™μž‘ κ°€λŠ₯)
  2. 이동 : μƒν•˜μ’Œμš° 1μΉΈ

μ€‘μš” 아이디어 : μžλ¬Όμ‡  λ°°μ—΄ ν™•μž₯


μ‹œκ°„λ³΅μž‘λ„

O(n^4), O(n^2 * m^2)
μžλ¬Όμ‡ μ™€ μ—΄μ‡ μ˜ μ΅œλŒ€ ν¬κΈ°λŠ” 20 * 20으둜, μ‹œκ°„ 초과λ₯Ό μ•”μ‹œν•˜λŠ” μ—°μ‚°νšŸμˆ˜ 1μ–΅κ³ΌλŠ” 거리가 λ©€λ‹€. λ”°λΌμ„œ 브루트포슀 μ•Œκ³ λ¦¬μ¦˜(μ™„μ „ 탐색)을 μ‹œλ„ν•΄λ΄„μ§ ν•˜λ‹€.

이 λ¬Έμ œλŠ” μžλ¬Όμ‡  배열을 3n * 3n으둜 ν™•μž₯ν•œ ν›„, κ°€λŠ₯ν•œ λͺ¨λ“  μ˜μ—­μ— λŒ€ν•΄ μ—΄μ‡  m * m 을 λŒ€μ‘°ν•΄λ΄μ•Ό ν•œλ‹€. λ”°λΌμ„œ μžλ¬Όμ‡ λ₯Ό 탐색함과 λ™μ‹œμ— μ—΄μ‡ λ₯Ό νƒμƒ‰ν•˜λ―€λ‘œ O(n^2 * m^2) 이닀. 일반적으둜 ν‘œν˜„ν•˜λ©΄ O(n^4) 으둜, μ‹€μ œλ‘œ 사쀑 for문을 μ‚¬μš©ν•œλ‹€.


μ•Œκ³ λ¦¬μ¦˜ : κ΅¬ν˜„, 브루트포슀 (μ™„μ „ 탐색)

문제 μ΄ν•΄λŠ” μ‰½μ§€λ§Œ μžλ¬Όμ‡  λ°°μ—΄ ν™•μž₯μ΄λΌλŠ” 아이디어λ₯Ό λ– μ˜¬λ¦¬μ§€ λͺ»ν•΄ ν•˜λ“œμ½”λ”©λ§Œ ν•˜λ‹€κ°€ κ³ μƒκ³ μƒν•œ λ¬Έμ œμ΄λ‹€. μ—΄μ‡ μ˜ νšŒμ „, μžλ¬Όμ‡ μ— μ—΄μ‡ λ₯Ό λΌμ›Œ 넣은 ν›„ λΉΌκΈ° 처럼 λ‹¨μˆœν•΄ λ³΄μ΄λŠ” λ™μž‘λ„ 생각보닀 κ΅¬ν˜„ν•˜κΈ° μ–΄λ €μ› λ‹€.


βœοΈλ‚΄ μ†ŒμŠ€μ½”λ“œ

  • create_graph() : μžλ¬Όμ‡  배열을 3n * 3n으둜 ν™•μž₯μ‹œν‚€λŠ” ν•¨μˆ˜λ‹€. 3n * 3n 배열을 μƒμ„±ν•œ ν›„, κ°€μš΄λ°μ— μžλ¬Όμ‡ λ₯Ό λ°°μΉ˜ν•œλ‹€.
  • rotate() : μ—΄μ‡ λ₯Ό μ‹œκ³„λ°©ν–₯으둜 90도 νšŒμ „μ‹œν‚¨λ‹€.
  • unlock() : κ°€μš΄λ°μ— μœ„μΉ˜ν•œ μžλ¬Όμ‡ μ˜ λͺ¨λ“  valueκ°€ 1인지 ν™•μΈν•œλ‹€.
  • solution() : 메인 ν•¨μˆ˜λ‹€. 사쀑 for문으둜 μžλ¬Όμ‡  λ°°μ—΄ graphλ₯Ό 탐색함과 λ™μ‹œμ— μ—΄μ‡ λ₯Ό λΌμ›Œ λ„£μŒ - unlock인지 확인 - μ—΄μ‡ λ₯Ό λΉΌλŠ” 일련의 κΈ°λŠ₯을 λ™μž‘ν•œλ‹€.
  def create_graph(n, lock):
      graph = [[0] * (n*3) for _ in range(n * 3)]
      for i in range(n):
          for j in range(n):
              graph[i + n][j + n] = lock[i][j]
      return graph


  def unlock(n, graph):
      for i in range(n, n * 2):
          for j in range(n, n * 2):
              if graph[i][j] != 1:
                  return False
      return True


  def rotate(m, key):
      nkey = [[0] * m for _ in range(m)]
      for i in range(m):
          for j in range(m):
              nkey[j][-i + m - 1] = key[i][j]
      return nkey


  def solution(key, lock):
      n, m = len(lock), len(key)
      graph = create_graph(n, lock)

      for _ in range(4):  # 90, 180, 270, 360
          key = rotate(m, key)
          for x in range(n * 2):
              for y in range(n * 2):

                  for i in range(m):
                      for j in range(m):
                          graph[x + i][y + j] += key[i][j]

                  if unlock(n, graph):
                      return True

                  for i in range(m):
                      for j in range(m):
                          graph[x + i][y + j] -= key[i][j]

      return False