Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[01주차 김동주] 소트 #1

Merged
merged 1 commit into from
Oct 21, 2023
Merged
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
32 changes: 32 additions & 0 deletions 01주차/김동주/1071.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
MAX_NUM = 1000


def solve(N: int, A: list[int]):
counter = [0] * (MAX_NUM+1)
for a in A:
counter[a] += 1
build(N, counter)
Comment on lines +4 to +8
Copy link
Member Author

Choose a reason for hiding this comment

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

문제에서 숫자의 배열이 주어지는데 숫자는 최대 50개고, 각 숫자는 1,000보다 작거나 같은 자연수 또는 0입니다.

이것을 연속된 두 수가 연속된 값이 아니게만 정렬하면 되는데,
우선 각 숫자의 등장 횟수를 세어봅시다.



def build(N: int, counter: list[int], stack: list[int] = []):
if len(stack) == N:
print(' '.join(map(str, stack)))
exit()
Comment on lines +12 to +14
Copy link
Member Author

Choose a reason for hiding this comment

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

모든 숫자를 다 채웠으면 완성된 수열을 출력하고 프로그램을 종료합니다.

for n in generate_possible_numbers(counter, stack):
stack.append(n)
counter[n] -= 1
build(N, counter, stack)
counter[n] += 1
stack.pop()
Comment on lines +11 to +20
Copy link
Member Author

Choose a reason for hiding this comment

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

이어서 각 숫자 별 등장 횟수를 센 counter 배열과, 스택만으로 문제에서 요구하는 수열을 만들 수가 있습니다.

스택에는 만들어진/완성된 수열이 담기게 됩니다.

Copy link
Member

Choose a reason for hiding this comment

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

오 아직 스택 활용하는 부분이 익숙치 않은데 이런식으로 적용하면 비슷한 다른 문제도 다양하게 적용시킬 수 있겠군요 참고하겠습니다 ㅎㅎ

Comment on lines +16 to +20
Copy link
Member Author

Choose a reason for hiding this comment

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

여기서는 가능한 수열 조합을 그리디하게 만들어가다가, 더 이상 문제의 조건을 만족하는 수열을 만들 수 없을 때 다시 stack의 top으로 되돌아가며 다른 조합을 찾아보게 됩니다.

뒤로 돌아가서 다시 추적을 한다는 의미에서 백트레킹이라고 부를 수 있지 않을까 싶네요



def generate_possible_numbers(counter: list[int], stack: list[int]):
Copy link
Contributor

Choose a reason for hiding this comment

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

저.. 좀 초짜같은 놀라움이긴 한데요, 파이썬에서 이렇게 타입 지정할 때 리스트 안에 들어갈 타입까지도 지정이 가능한 걸 지금 알았네요.
요즘 파이썬으로 프로그램 작성하면 최대한 타입 지정해서 사용하려고 하는데, 참고해보겠습니당.. ☺️

for i in range(MAX_NUM+1):
if counter[i] > 0 and (not stack or i != stack[-1]+1):
yield i
Copy link
Member

Choose a reason for hiding this comment

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

yield 라는 키워드를 처음봐서 검색해보고 왔는데 성능 측면에서 이점을 보기위해서 사용한다고 하는데 그점을 노리고 사용하신건지 아님 또 다른 이유가 있는지 궁금합니다



if __name__ == "__main__":
N = int(input())
A = list(map(int, input().split()))
solve(N, A)
Loading