이진분류와 하노이 탑
숫자 찾기
백준 1920
N개의 정수 A[1], A[2], …, A[N]이 주어져 있을 때, 이 안에 X라는 정수가 존재하는지 알아내는 프로그램을 작성하시오.
-> 정말 쉬운 문제이지만, 배운 것을 적용하기 위해서 이진 탐색 관련 알고리즘으로 구현하였다.
우선 처음에 작성한 코드
def binary_search(ordered_list, target):
left, right = 0, len(ordered_list) - 1
mid = (left + right) // 2
if left == right:
if ordered_list[left] == target:
return True
else:
return False
elif ordered_list[mid] > target:
mid -= 1
return binary_search(ordered_list[left:mid], target)
elif ordered_list[mid] < target:
left = mid + 1
right += 1
return binary_search(ordered_list[left:right], target)
else:
return True
data = [1, 2, 4, 7, 13, 17, 19]
t = 0
print(binary_search(data, t))
이 코드의 문제점은 인덱스값을 반환하지 않는 것에 있다. 그리고 재귀를 이용하기 위해 쓸데없는 슬라이스 객체를 만들어 내는 것 또한 문제다. 물론 문제에서는 참과 거짓만을 요구하였지만 탐색 과정에는 인덱스(위치) 값 도출이 중요하다고 생각한다. 정석으로는 while문을 이용하면 깔끔하다.
import bisect
import random
def binary_search(ordered_list, target):
index = bisect.bisect_left(ordered_list, target)
if index < len(ordered_list) and ordered_list[index] == target:
return index
else:
return None
a = int(input())
list_a = list(input().split())
list_a.sort()
b = int(input())
list_b = list(input().split())
for i in range(b):
print(binary_search(list_a, list_b[i]))
bisect를 이용한 탐색이다.
_index < len(ordered_list)_
개인적으로 이 부분이 가장 중요하다고 생각한다.
-> bisect_left란?
배열에서 주어진 값을 정렬된 상태로 삽입할 수 있는 index 출력
하노이 탑
백준 11729번
def hanoi_top(n):
if n == 1:
return 1
else:
return 2 * hanoi_top(n-1) + 1
num = 3
print(hanoi_top(num))
단순히 횟수만 구하는 코드이다. 다음은 문제의 요구에 맞게 변화를 주었다.
# 하노이 탑 문제
# 구하고자 하는 것 : 최소로 옮기는 것은 몇 번일까?
def hanoi_top(n, dstn, start=1):
dict = [1, 2, 3]
dict.remove(dstn)
dict.remove(start)
subdstn = dict[0]
if n == 1:
print("{} {}".format(start, dstn))
else:
hanoi_top(n-1, subdstn, start)
print("{} {}".format(start, dstn))
start = dstn
hanoi_top(n-1, dstn, start=subdstn)
num_circle = int(input())
print(pow(2, num_circle)-1)
hanoi_top(num_circle, 3)
옮길 때마다 횟수를 누적시키는 것은 글로벌 변수를 어떻게 쓰는지 몰라서 구현 못했다. 하노이 경우의 수는 알고 있었기에 정답만 맞추자는 식으로 짰다. 다음은 모법 답안이다.
def hanoi(disks, src, dst, extra):
if disks == 1:
hanoi.count += 1
print("{} {}".format(src, dst))
else:
hanoi(disks-1, src, extra, dst)
hanoi.count += 1
print("{} {}".format(src, dst))
hanoi(disks-1, extra, dst, src)
hanoi.count = 0
num = int(input())
print(pow(2, num)-1)
hanoi(num, 1, 3, 2)
차이점은 백준 채점 기준 작동 시간이 200ms 줄었다는 것이고
문제는 횟수를 표시함에 있어서 모범답안을 그대로 가져왔지만 저 부분은 나중에 생각하기로 했다.
리스트를 이용해서 해결했지만 작동 시간이 2배나 느는 바람에 폐기했다.
'알고리즘' 카테고리의 다른 글
[알고리즘] 문제 풀이 (0) | 2024.03.18 |
---|---|
순열과 조합을 구현해보자 (0) | 2024.01.08 |
무방향 그래프와 서로소 집합 (0) | 2023.12.10 |
n-queen 구현 (1) | 2023.12.03 |
11.28 알고리즘 문제풀이 (1) | 2023.11.28 |