[백준] 1300번 K번째 수 _ Python

2023. 11. 17. 01:45·Algorithms/Binary Search

https://www.acmicpc.net/problem/1300

[초기 접근 방법(X)]

1. N^2의 [i][j] 값을 모두 lst에 넣으려면 시간복잡도가 이미 O(N^2)으로 시간초과이다.

2. 그러면? 시간복잡도를 줄일 수 있는 방법은, 처음부터 [i][j] 값을 lst에 넣지 않는 것

3. 그런 [i][j] 값을 전부 넣지않고, 어떤 값을 lst에 넣어야 하는가?

 

에서 시작했다.

 

대각선을 기준으로 중앙값이 가장 크므로,

이분탐색을 하여 몇번째 대각선인지 찾고 남은 인덱스만큼 이동탐색하면 K번째 수를 찾으려고 했다.

 

 

 

[생각]

위 방식대로 로직을 짜고 풀었지만 결과는 "틀렸습니다"

저 로직을 생각하는데도 시간을 많이 썼던 문제라서, 미련없이 정답 코드를 참고했다...

일단 K번째 수는 '1행의 원소들'이 존재하므로 무조건 K보다 작다.

따라서 binary search의 범위는 1~K로 좁혀진다.

그리고 위 범위에 해당하는 수 mid를 정하고, 각 행의 mid보다 작은 수를 카운트한다.

카운트한 수가 문제에서 원하는 K에 근접하도록 이분탐색을 계속 진행해주고, 그 값을 출력하면 되는 문제이다.

 

 

 

[초기 코드]

# 맞는지 보자..
# moveIdx와 reverse 개념 수정 (자기자신 포함 안 했었음)
# lst[idx] == K 수정

N = int(input()) # 배열의 크기
K = int(input()) # 오름차순 정렬했을 때, k번째 인덱스

lst = [0] # 경계값 리스트
num = 0
# 앞 경계
for i in range(1, N+1):
    num += i
    lst.append(num)

# 뒤 경계
for i in range(1, N):
    num += (N-i)
    lst.append(num)


def search(start, end):
    while start < end:
        mid = (start + end) // 2

        if lst[mid] < K: # K, 경계값 lower_bound 탐색
            start = mid + 1

        else:
            end = mid

    # lower_bound(K 이상값) 반환
    # lst[end] : K 다음 경계값
    return end

idx = search(0, len(lst)-1) # 시작, 끝 인덱스
if lst[idx] == K:
    row = 1
    col = 1

    judge = True
    for _ in range(idx-1):
        if judge:
            col += 1
            judge = False

        else:
            row += 1
            judge = True

    print(row*col)

else:
    moveIdx = K - lst[idx-1] - 1

    # 대각선 경계를 기준으로 아래
    if lst[N] < K:
        row = N
        col = idx-N+1

    # 위
    else:
        row = idx
        col = 1

    # 왔다갔다 탐색한다.
    reverse = True
    for _ in range(moveIdx):
        if reverse:
            row, col = col, row
            reverse = False

        else:
            row += 1
            col -= 1
            reverse = True

    print(row * col)

 

 

[참고해서 작성한 코드]

# 풀이 시간 : 2시간 + 1시간
# 시간복잡도 : O(Nlog(K))
# 공간복잡도 : O(1)
# 참고 : https://kbw1101.tistory.com/29

# 이 문제의 핵심은, lst[K]의 정의이다.
    # lst[K] = x 일 때,
    # x보다 작거나 같은 값이 K개 있다는 의미

    # 따라서 범위(1~K) 내에서 mid 값보다 작거나 같은 값이 K개가 되는 최적값을 찾아 반환한다.

N = int(input())
K = int(input())

def search(start, end):
    while start < end:
        mid = (start + end) // 2

        # mid보다 작거나 같은 i*j값 찾기
        cnt = 0
        for i in range(1, N + 1):
            # 각 행의 col 값은 행(i)의 배수이므로,
                # 작은 값을 찾을 때 //i 를 해주면 된다.
            cnt += min(mid // i, N)

        if cnt < K:
            start = mid + 1

        else:
            end = mid

    return end


# end가 'K'인 이유
    # B[k]의 값은 k보다 작거나 같기 때문이다.
    # 1행의 값 때문에 '1~n'은 보장된다.
print(search(1, K))
저작자표시 (새창열림)

'Algorithm > Binary Search' 카테고리의 다른 글

[백준] 1939번 중량제한 _ Python  (0) 2023.11.20
[백준] 11663번 선분 위의 점 _ Python  (1) 2023.11.13
[백준] 13397번 구간 나누기 2 _ Python  (0) 2023.11.12
[백준] 19637번 IF문 좀 대신 써줘 _ Python  (0) 2023.11.11
[백준] 2417번 정수 제곱근 _ Python  (1) 2023.11.11
'Algorithms/Binary Search' 카테고리의 다른 글
  • [백준] 1939번 중량제한 _ Python
  • [백준] 11663번 선분 위의 점 _ Python
  • [백준] 13397번 구간 나누기 2 _ Python
  • [백준] 19637번 IF문 좀 대신 써줘 _ Python
wch_t
wch_t
  • wch_t
    끄적끄적(TIL)
    wch_t
  • 글쓰기 관리
  • 전체
    오늘
    어제
    • 분류 전체보기 (170) N
      • Architecture (0)
      • Algorithm (67)
        • Math (5)
        • Simulation (1)
        • Data Structure (4)
        • DP (7)
        • Brute Fource (10)
        • Binary Search (6)
        • Greedy (2)
        • Graph (11)
        • Mst (1)
        • Shortest path (10)
        • Two Pointer (1)
        • Tsp (3)
        • Union Find (2)
        • Mitm (1)
      • CS (2)
        • 데이터베이스 (5)
        • 네트워크 (5)
      • DB (6)
      • DevOps (17)
        • AWS (9)
        • Docker (1)
        • CI-CD (5)
      • Error (1)
      • Project (0)
        • kotrip (0)
      • Spring (59)
        • 끄적끄적 (5)
        • 기본 (9)
        • MVC 1 (7)
        • MVC 2 (11)
        • ORM (8)
        • JPA 1 (7)
        • JPA 2 (5)
        • Spring Data Jpa (7)
      • Test (2)
      • TIL (5) N
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    docker: not found
    spring-cloud-starter-bootstrap
    aws secrets manager
    spring-cloud-starter-aws-secrets-manager-config
    view algorithm
    백준 3015 파이썬
    apache poi
    scope
    Merge
    애플
    docker
    form_post
    백준 17299 파이썬
    Jenkins
    백준 17289 파이썬
    Sxssf
    TempTable
    response_mode
  • 최근 댓글

  • hELLO· Designed By정상우.v4.10.3
wch_t
[백준] 1300번 K번째 수 _ Python
상단으로

티스토리툴바