Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions 17주차/(P)60059/60059_python_kimjoohye.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import numpy as np
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

저는 numpy를 코딩 테스트에 써본 적이 없었는데 파이썬인 만큼 이런 라이브러리 활용을 잘해야 되겠다고 느꼈습니다..


#key와 lock의 각각의 요소를 합친 배열의 결과 - answer
#answer의 배열의 요소가 모두 1이 아니면 false
def checklock(answer):
for i in answer:
for j in i:
if j!=1:
return False
return True

#lock을 key의 size-1만큼 더해서 확장시킨 배열로 만들고 가장자리부분 0으로 초기화
#key와 lock의 블록이 하나씩, 두개씩, 세개씩, ... 점점 많아지게 겹쳐서 더한 후
#(겹쳐지는 부분이 많아지다가 모든 key요소와 모든 lock의 요소가 합쳐진 다음 다시 겹쳐지는 부분이 줄어듬)
#원래의 lock size에 맞게 배열 slice - checklock함수로 unlock할 수 있는지 확인
def unlock(answerkey, lock):
N = len(lock)
M = len(answerkey)
#확장
lock = np.pad(lock, (M-1, M-1))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pad를 하게되면 어떻게 lock이 변화하나요 ?


#확장시킨 배열에 key를 오른쪽 아래방향으로 한칸씩 옮겨가면서 더하고 원래의 lock size에 맞게 배열 slice
newM = N+M-1
for i in range(newM):
for j in range(newM):
resultlock = lock.copy()
resultlock[i:i+M,j:j+M] = lock[i:i+M,j:j+M] + answerkey[:][:]
if checklock(resultlock[M-1:M+N-1,M-1:M+N-1]):
return True

return False
def solution(key, lock):
#numpy array로 변경
answerkey = np.array(key)
lock = np.array(lock)

flag = False

for i in range(4):
# i*90만큼 key회전 -> 0, 90, 180, 270만 수행
answerkey = np.rot90(answerkey, i)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

회전하는 함수가 numpy에 존재하는지 몰랐습니다...

flag = unlock(answerkey, lock)
if flag == True:
break
return flag
46 changes: 46 additions & 0 deletions 17주차/20055/20055_python_kimjoohye.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# [컨베이어 벨트 위의 로봇]
# 벨트가 각 칸 위에 있는 로봇과 함께 한 칸 회전한다.
# 가장 먼저 벨트에 올라간 로봇부터, 벨트가 회전하는 방향으로 한 칸 이동할 수 있다면 이동한다. 만약 이동할 수 없다면 가만히 있는다.
# 로봇이 이동하기 위해서는 이동하려는 칸에 로봇이 없으며, 그 칸의 내구도가 1 이상 남아 있어야 한다.
# 올리는 위치에 있는 칸의 내구도가 0이 아니면 올리는 위치에 로봇을 올린다.
# 내구도가 0인 칸의 개수가 K개 이상이라면 과정을 종료한다. 그렇지 않다면 1번으로 돌아간다.

N, K = map(int, input().split())
queue = list(map(int, input().split())) #컨베이어벨트
robot = [0 for i in range(len(queue))] #robot유무
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

벨트 / 로봇이 벨트 어디에 존재하는지 이 둘의 구조를 따로 관리한 점은 저랑 같습니다!


countStep = 0

while True:
countStep += 1
# 컨베이어 벨트 & robot 회전
queue.insert(0, queue.pop())
robot.insert(0, robot.pop())
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

회전을 pop()을 이용해서도 구현이 가능하겠군요! 자료구조를 잘 써야하는 문제였던거 같아요 ..

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

파이썬에서는 list.insert(0)의 경우 O(N)이 소요됩니다. 앞과 뒤에 append를 빠르게 (O(1))할 수 있는 collections.deque를 활용하면 될 것 같아요! deque.rotate()를 통해서 회전도 가능하다는 장점이 많습니다.
from collections import deque


# robot 내리기
if robot[N-1] == 1:
robot[N-1] = 0

# robot move
for i in range(N - 1, -1, -1):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

로봇이 N에서 내린다는 점을 감안해서 뒤쪽부터 봐주면 되는 관찰이 이번 문제의 핵심이었던 것 같습니다 💯

if robot[i] == 1 and robot[i + 1] == 0 and queue[i + 1] > 0:
queue[i + 1] -= 1
robot[i], robot[i + 1] = robot[i + 1], robot[i]

if queue.count(0) >= K:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

저는 이 조건을 아예 while문 조건에 추가했습니다!

break

# robot 내리기
if robot[N-1] == 1:
robot[N-1] = 0

# robot 올리기
if queue[0] > 0:
queue[0] -= 1
robot[0] = 1

if queue.count(0) >= K:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

제한이 작아서 괜찮지만, 매번 count를 하는 것도 O(N)으로 큰 제한에서는 부담이 될 수 있습니다. 따로 내구도가 0이 될 때마다 카운트하는 변수를 만들면 부하를 줄일 수 있겠네요!

break

print(countStep)