SELECT
COUNT(*) AS fish_count
FROM
fish_info
WHERE
length IS NULL
;
-- 1
SELECT
id
, length
FROM
fish_info
ORDER BY
length DESC
, id ASC
LIMIT 10
;
-- 2
WITH length_rank AS (
SELECT
*
, RANK() OVER (ORDER BY length DESC) AS rnk
FROM
fish_info
)
SELECT
id
, length
FROM
length_rank
WHERE
rnk <= 10
ORDER BY
rnk
, id
;
def solution(n,a,b):
from math import ceil
answer = 0
while a!=b:
answer += 1
a, b = ceil(a/2), ceil(b/2)
return answer
def solution(n,a,b):
return ((a-1)^(b-1)).bit_length()
1을 빼는 것은 선수의 위치를 0-index 형태로 바꾸기 위함인 것 같고요.
a, b는 각각 선수의 위치이고 이를 2비트 수로 표현했을 때a, b가 인접한 위치로 가려면, 두 비트가 같을 때는 0을 더하고 두 비트가 다를 때는 1을 더하는 XOR 연산으로 생각할 수 있겠네요.
토너먼트 트리를 그렸을 때, 윗단을 최상위 비트, 아래단을 최하위 비트로 생각하면 이해되실 것 같네요. 가령, 5(101)의 가장 앞의 비트값(최상위)가 트리의 꼭대기
(a, b 를 xor 취하는 과정에서 ab 사이의 거리가 가까우면 상위비트는 차이가 나지 않겠죠? 거꾸로 ab 사이의 거리가 멀면 상위비트가 차이 날 거고요. 그래서 xor 연산 결과의 길이를 리턴해주면 라운드가 나오는 아이디어인것으로 보여요.)
def solution(n, a, b):
answer = 0
while a != b:
answer += 1
a, b = (a + 1) // 2, (b + 1) // 2
return answer
대진표를 그려보면 각 라운드에 진출 할 때마다 숫자가 2로 나누어지는 것을 볼 수 있을 것이다.
a와 b를 나누고 난 값이 같아지는 경우에는 만나서 대결을 진행한 것이라고 볼 수 있기 때문에, 우리는 a와 b의 값이 같아질 때까지 2로 나누어주면 된다.
a와 b에 1을 더하는 이유는, 각 숫자가 홀수일 경우에 잘못 배정되는 경우를 방지하기 위해서이다.
예를 들어서 7을 2로 나누면 3.5가 되어서 정수만 보면 3이 되는데, 이렇게 되면 우리가 기대하는 바와 달라지므로 미리 1을 더해서 2로 나눈다.
그렇게 하면 정상적으로 잘 배치되는 것을 볼 수 있다.
def solution(n,a,b):
# 발생할 수 있는 최대 라운드 수 계산
max_round = 0
while 2 ** max_round < n:
max_round += 1
# 이진 탐색 적용
a, b = min(a, b), max(a, b) # 큰 수, 작은 수 구분
mid = n // 2 # 최초 중간값
lower = 0 # 최초 최소값
upper = n # 최초 최대값
while True:
# 탈출 조건 // 두 수가 포함된 라운드가 서로 다를 경우
if a <= mid and b > mid:
break
# 작은 수가 중간값보다 클 경우(라운드에서 두 수가 같은 그룹에 있을 경우)
elif a >= mid:
lower = mid
mid = (mid + upper) // 2
max_round -= 1 # 라운드값 -1
# 큰 수가 중간값보다 작거나 같을 경우(라운드에서 두 수가 같은 그룹에 있을 경우)
elif b <= mid:
upper = mid
mid = (mid + lower) // 2
max_round -= 1 # 라운드값 -1
return max_round
대진표를 손으로 그려보다가 반으로 나누어 전후를 살핀다는 점이 이진탐색과 동일하다고 생각하여 이진탐색 기법을 적용하기로 결정
발생할 수 있는 최대 라운드의 수를 계산하기 위하여 while Loop을 활용, 2의 x제곱이 n과 같아지는 시점까지 max_round 변수를 1씩 증가시킴.
이진탐색을 적용하기 위하여 주어진 변수 a와 b의 대소를 비교하여 작은 수를 a에, 큰 수를 b에 재할당하고, 최초 중간값/최소값/최대값을 설정
while Loop을 무한 반복하되, 탈출조건으로 두 수가 서로 다른 라운드에 포함되어있을 경우를 설정
이후 라운드에서 두 수가 같은 그룹에 있을 경우를 두 경우로 분할(작은 수가 mid 보다 클 경우, 또는 큰 수가 mid보다 작을 경우)하여 해당 경우에는 max_round를 1씩 뺌

my.ini 파일 수정:
