๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐Ÿฆ„ | ์ฝ”๋”ฉํ…Œ์ŠคํŠธ ์—ฐ์Šต/BOJ

[Python] ๋ฐฑ์ค€ 23883 ์•Œ๊ณ ๋ฆฌ์ฆ˜ ์ˆ˜์—… - ์„ ํƒ ์ •๋ ฌ 3

by KASSID 2023. 4. 12.

๋ชฉ์ฐจ

    728x90

    ๋ฌธ์ œ

    ์˜ค๋Š˜๋„ ์„œ์ค€์ด๋Š” ์„ ํƒ ์ •๋ ฌ ์ˆ˜์—… ์กฐ๊ต๋ฅผ ํ•˜๊ณ  ์žˆ๋‹ค. ์•„๋น ๊ฐ€ ์ˆ˜์—…ํ•œ ๋‚ด์šฉ์„ ํ•™์ƒ๋“ค์ด ์ž˜ ์ดํ•ดํ–ˆ๋Š”์ง€ ๋ฌธ์ œ๋ฅผ ํ†ตํ•ด์„œ ํ™•์ธํ•ด๋ณด์ž.

    N๊ฐœ์˜ ์„œ๋กœ ๋‹ค๋ฅธ ์–‘์˜ ์ •์ˆ˜๊ฐ€ ์ €์žฅ๋œ ๋ฐฐ์—ด A๊ฐ€ ์žˆ๋‹ค. ์„ ํƒ ์ •๋ ฌ๋กœ ๋ฐฐ์—ด A๋ฅผ ์˜ค๋ฆ„์ฐจ์ˆœ ์ •๋ ฌํ•  ๊ฒฝ์šฐ K ๋ฒˆ์งธ ๊ตํ™˜๋˜๋Š” ์ˆ˜๋ฅผ ๊ตฌํ•˜์ž.

    N์ด ๋งค์šฐ ์ปค์„œ ์‹œ๊ฐ„ ์ดˆ๊ณผ๋ฅผ ๊ณ ๋ฏผํ•˜๊ณ  ์žˆ๋Š” ์šฐ๋ฆฌ ์„œ์ค€์ด๋ฅผ ๋„์™€์ฃผ์ž.

    ํฌ๊ธฐ๊ฐ€ N์ธ ๋ฐฐ์—ด์— ๋Œ€ํ•œ ์„ ํƒ ์ •๋ ฌ ์˜์‚ฌ ์ฝ”๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

    selection_sort(A[1..N]) { # A[1..N]์„ ์˜ค๋ฆ„์ฐจ์ˆœ ์ •๋ ฌํ•œ๋‹ค.
        for last <- N downto 2 {
            A[1..last]์ค‘ ๊ฐ€์žฅ ํฐ ์ˆ˜ A[i]๋ฅผ ์ฐพ๋Š”๋‹ค
            if (last != i) then A[last] <-> A[i]  # last์™€ i๊ฐ€ ์„œ๋กœ ๋‹ค๋ฅด๋ฉด A[last]์™€ A[i]๋ฅผ ๊ตํ™˜
        }
    }

    ์ž…๋ ฅ

    ์ฒซ์งธ ์ค„์— ๋ฐฐ์—ด A์˜ ํฌ๊ธฐ N(5 ≤ N ≤ 500,000), ๊ตํ™˜ ํšŸ์ˆ˜ K(1 ≤ K ≤ N)๊ฐ€ ์ฃผ์–ด์ง„๋‹ค.

    ๋‹ค์Œ ์ค„์— ์„œ๋กœ ๋‹ค๋ฅธ ๋ฐฐ์—ด A์˜ ์›์†Œ A1, A2, ..., AN์ด ์ฃผ์–ด์ง„๋‹ค. (1 ≤ Ai ≤ 109)

    ์ถœ๋ ฅ

    K ๋ฒˆ์งธ ๊ตํ™˜๋˜๋Š” ๋‘ ๊ฐœ์˜ ์ˆ˜๋ฅผ ์ž‘์€ ์ˆ˜๋ถ€ํ„ฐ ํ•œ ์ค„์— ์ถœ๋ ฅํ•œ๋‹ค. ๊ตํ™˜ ํšŸ์ˆ˜๊ฐ€ K ๋ณด๋‹ค ์ž‘์œผ๋ฉด -1์„ ์ถœ๋ ฅํ•œ๋‹ค.

    ์˜ˆ์ œ ์ž…๋ ฅ 1 ๋ณต์‚ฌ

    5 2
    3 1 2 5 4
    

    ์˜ˆ์ œ ์ถœ๋ ฅ 1 ๋ณต์‚ฌ

    2 3
    

    3 1 2 5 4 (4์™€ 5๊ฐ€ ๊ตํ™˜๋จ) -> 3 1 2 4 5 (A[1..4]์—์„œ 4๊ฐ€ ๊ฐ€์žฅ ํฌ๋ฏ€๋กœ ๊ตํ™˜์ด ๋ฐœ์ƒํ•˜์ง€ ์•Š์Œ) -> 3 1 2 4 5 (2์™€ 3์ด ๊ตํ™˜๋จ) -> 2 1 3 4 5 (1๊ณผ 2๊ฐ€ ๊ตํ™˜๋จ) -> 1 2 3 4 5. ์ด 3ํšŒ ๊ตํ™˜์ด ๋ฐœ์ƒํ•˜๊ณ  ๋‘ ๋ฒˆ์งธ ๊ตํ™˜์€ 2์™€ 3์ด๋‹ค.

    ์˜ˆ์ œ ์ž…๋ ฅ 2 ๋ณต์‚ฌ

    5 4
    3 1 2 5 4
    

    ์˜ˆ์ œ ์ถœ๋ ฅ 2 ๋ณต์‚ฌ

    -1
    

    ๊ตํ™˜ ํšŸ์ˆ˜ 3์ด K ๋ณด๋‹ค ์ž‘์œผ๋ฏ€๋กœ -1์„ ์ถœ๋ ฅํ•œ๋‹ค.

     


    ์ฝ”๋“œ

    import sys
    
    def selection_sort(N, K, A):
        # ์ •๋ ฌ๋œ ๋ฆฌ์ŠคํŠธ
        sortedA = sorted(A)
        numDict = {}
        
        # ๋”•์…”๋„ˆ๋ฆฌ  key : A์›์†Œ value : ์ •๋ ฌ ์ „ ์ธ๋ฑ์Šค
        for i, j in enumerate(A):
          numDict[j] = i
          
        cnt = 0
        for i in range(N-1, -1, -1): # i : ํ˜„์žฌ ์ •๋ ฌํ•  ์ธ๋ฑ์Šค
            if sortedA[i] != A[i]: # ํ˜„์žฌ ์ธ๋ฑ์Šค๊ฐ€ ์•„๋‹ˆ๋ฉด?
              result = [A[i], sortedA[i]]
              A[i], A[numDict[sortedA[i]]] = A[numDict[sortedA[i]]], A[i]
              numDict[result[0]], numDict[result[1]] = numDict[result[1]], numDict[result[0]]
              cnt += 1
            if K == cnt : print(*result);return
        if K > cnt : print(-1);return
    
    
    N, K = map(int, sys.stdin.readline().rstrip().split())
    A = list(map(int, sys.stdin.readline().rstrip().split()))
    selection_sort(N, K, A)

    ๋ฆฌ๋ทฐ

    ๋‹จ์ˆœํžˆ ์ˆœ์„œ๋Œ€๋กœ ์„ ํƒ์ •๋ ฌ์„ ํ•˜์˜€์„ ๋•Œ ๋ฐฐ์—ด์˜ ํฌ๊ธฐ๋กœ ์ธํ•ด ์‹œ๊ฐ„ ์ดˆ๊ณผ๊ฐ€ ๋˜๋Š” ๋ฌธ์ œ์˜€๋‹ค.

     

    ๊ฐ€์žฅ ๋จผ์ € ์‹œ๊ฐ„ ๋ณต์žก๋„ ๋ถ€๋ถ„์„ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด์„œ ์–ด๋–ค ๊ฒƒ์„ ์‚ฌ์šฉํ•ด๋ณผ๊นŒ? ๋ผ๋Š” ์งˆ๋ฌธ์—

    ํ˜„์žฌ ์ •๋ ฌ ์„ธ์…˜์˜ ๊ฐ€์žฅ ํฐ ๊ฐ’์„ ์ฐพ๋Š” ๋ถ€๋ถ„์„ ํž™ ์ •๋ ฌ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ์‹œ๋„ํ•˜์˜€๋‹ค.

    ์ด๋ฅผ ์œ„ํ•ด์„œ heapq ๋ชจ๋“ˆ์„ ์‚ฌ์šฉํ•˜๋ ค ํ–ˆ์ง€๋งŒ

    ๋งค ๋ฐ˜๋ณต ๋Œ€์ƒ ๋ถ€๋ถ„๋ฆฌ์ŠคํŠธ๋งˆ๋‹ค ํž™ ์ •๋ ฌ์„ ์œ„ํ•ด heapify๋ฅผ ํ•ด์•ผํ•˜๋Š”๋ฐ

    ์ด๋ฅผ ์œ„ํ•ด์„œ ๊ณ„์† ๋”ฐ๋กœ ํž™์„ ์ƒ์„ฑํ•˜๊ณ  ์ตœ๋Œ€๊ฐ’์„ ์ฐพ๊ณ , ํ•ด๋‹น ๊ฐ’์˜ ์ธ๋ฑ์Šค๋ฅผ ๋‹ค์‹œ ์ฐพ์•„์•ผํ•˜๋Š” ์ ์ด

    ๋น„ํšจ์œจ์ ์ผ ๊ฒƒ ๊ฐ™์•„์„œ ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์„ ์ฐพ์•„๋ณด์•˜๋‹ค.

     

    ๊ทธ๋ž˜์„œ ๋‘ ๋ฒˆ์งธ๋กœ ๊ณ ๋ คํ•ด๋ณธ ๊ฒƒ์€ ๋”•์…”๋„ˆ๋ฆฌ๋ฅผ ์ด์šฉํ•˜๋Š” ๊ฒƒ์ด์—ˆ๋‹ค.

    ๋”•์…”๋„ˆ๋ฆฌ ์ž๋ฃŒํ˜•์€ ๋‚ด๋ถ€์ ์œผ๋กœ ํ•ด์‹œ ํ…Œ์ด๋ธ”์„ ์ด์šฉํ•˜๋ฏ€๋กœ ๋ฐ์ดํ„ฐ์˜ '์กฐํšŒ ๋ฐ ์ˆ˜์ •์ด O(1)'์˜ ์‹œ๊ฐ„๋ณต์žก๋„๋ฅผ ๊ฐ€์ง€๊ธฐ ๋•Œ๋ฌธ์—

    ์ด๋ฅผ ์ด์šฉํ•˜๋ฉด ์ ํ•ฉํ•˜์ง€ ์•Š์„๊นŒ? ๋ผ๊ณ  ์ƒ๊ฐํ•˜์˜€๋‹ค.

     

    1) ์ •๋ ฌ ๋ฆฌ์ŠคํŠธ ์ƒ์„ฑ๊ณผ ๋”•์…”๋„ˆ๋ฆฌ ์ƒ์„ฑ

     # ์ •๋ ฌ๋œ ๋ฆฌ์ŠคํŠธ
    sortedA = sorted(A)
    numDict = {}
    
    # ๋”•์…”๋„ˆ๋ฆฌ  key : A์›์†Œ value : ์ •๋ ฌ์ „ ์ธ๋ฑ์Šค
    for i, j in enumerate(A):
      numDict[j] = i

    ๋จผ์ € ์ตœ์•…์˜ ๊ฒฝ์šฐ์—๋„ nlogn์˜ ์‹œ๊ฐ„์„ ๋ณด์žฅํ•˜๋Š” Timsort์•Œ๊ณ ๋ฆฌ์ฆ˜์œผ๋กœ ๊ตฌํ˜„๋œ sorted()๋ฅผ ์ด์šฉํ•˜์—ฌ

    ์ฃผ์–ด์ง„ ๋ฆฌ์ŠคํŠธ A๋ฅผ ์ •๋ ฌํ•œ๋ฆฌ์ŠคํŠธ sortedA๋ฅผ ์ƒ์„ฑํ•˜์˜€๋‹ค.

     

    enumerate()๋ฅผ ์ด์šฉํ•˜์—ฌ numDIct ๋”•์…”๋„ˆ๋ฆฌ์—

    key = A์˜ ์›์†Œ, value=ํ•ด๋‹น ์›์†Œ์˜ ์ธ๋ฑ์Šค

    ๋กœ ์‚ฝ์ž…ํ•˜์˜€๋‹ค.

     

    2) ์„ ํƒ์ •๋ ฌ & ๊ฒฐ๊ณผ๊ฐ’ ์ฐพ๊ธฐ

    for i in range(N-1, -1, -1): # i : ํ˜„์žฌ ์ •๋ ฌํ•  ์ธ๋ฑ์Šค
        if sortedA[i] != A[i]: # ํ˜„์žฌ ์ธ๋ฑ์Šค๊ฐ€ ์•„๋‹ˆ๋ฉด?
          result = [A[i], sortedA[i]]
          A[i], A[numDict[sortedA[i]]] = A[numDict[sortedA[i]]], A[i]
          numDict[result[0]], numDict[result[1]] = numDict[result[1]], numDict[result[0]]
          cnt += 1
        if K == cnt : print(*result);return
    if K > cnt : print(-1);return

    sortedA์™€ A์˜ ๋งˆ์ง€๋ง‰ ์›์†Œ๋ถ€ํ„ฐ ๋น„๊ตํ•˜๋ฉฐ ์ •๋ ฌ์„ ์ง„ํ–‰ํ•œ๋‹ค.

    ๋งŒ์•ฝ ํ˜„์žฌ ์ธ๋ฑ์Šค์˜ ๊ฐ’์ด ์„œ๋กœ ๋‹ค๋ฅด๋‹ค๋ฉด A๋Š” ์ •๋ ฌ๋˜์–ด์•ผํ•œ๋‹ค.

     

    ์ •๋ ฌํ•  ๊ฐ’์˜ ์ธ๋ฑ์Šค๋Š” "numDict[sortedA[ํ˜„์žฌ์ธ๋ฑ์Šค]]"์— ๋‹ด๊ฒจ ์žˆ๋‹ค.

    ์ด๋ฅผ ์ด์šฉํ•˜์—ฌ A[ํ˜„์žฌ ์ธ๋ฑ์Šค] ์™€ A[numDict[sortedA[ํ˜„์žฌ์ธ๋ฑ์Šค]]] ๋ฅผ ์„œ๋กœ ๋ฐ”๊พธ์–ด ์ •๋ ฌํ•œ๋‹ค.

     

    ๋ฐ”๊พผ ๊ฒƒ์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ numDict์—๋„ ์ ์šฉํ•œ๋‹ค.

    ๋Œ“๊ธ€