[์ฝ”๋“œํŠธ๋ฆฌ ๐Ÿ’Ž5] ์‚ฐํƒ€์˜ ์„ ๋ฌผ ๊ณต์žฅ 2 (Python/ํŒŒ์ด์ฌ)

mingssoยท2023๋…„ 4์›” 5์ผ
0

Algorithm

๋ชฉ๋ก ๋ณด๊ธฐ
33/35

1๏ธโƒฃ ๋ฌธ์ œ

https://www.codetree.ai/training-field/frequent-problems/santa-gift-factory-2/description?page=3&pageSize=20&username=



2๏ธโƒฃ ์ฝ”๋“œ

2022 ์‚ผ์„ฑ ํ•˜๋ฐ˜๊ธฐ ๊ณต์ฑ„ ๊ธฐ์ถœ๋ฌธ์ œ
๋งํฌ๋“œ ๋ฆฌ์ŠคํŠธ๋กœ ํ’€์–ด์•ผํ•œ๋‹ค๋Š” ๊ฑด ์•Œ๊ฒ ๋Š”๋ฐ ์ฝ”๋“œ๋ฅผ ํšจ์œจ์ ์œผ๋กœ ์งœ๋Š” ๋ฐฉ๋ฒ•์„ ๋ชจ๋ฅด๊ฒ ์–ด์„œ ์ •๋‹ต ์ฝ”๋“œ๋กœ ๊ณต๋ถ€ํ–ˆ๋‹ค๐Ÿ˜…

q = int(input())
  
n, m = -1, -1  # n๊ฐœ์˜ ๋ฒจํŠธ, m๊ฐœ์˜ ๋ฌผ๊ฑด 
prev, next = [0] * 100001, [0] * 100001   # id์— ํ•ด๋‹นํ•˜๋Š” ์ƒ์ž์˜ prev, next๊ฐ’
head, tail, num = [0] * 100001, [0] * 100001, [0] * 100001  # ๊ฐ ๋ฒจํŠธ ๋ณ„ head id, tail id, ์„ ๋ฌผ ์ˆ˜ 

# 1) ๊ณต์žฅ ์„ค๋ฆฝ
def build(order):
    n, m = order[1], order[2]   
    belt = [[] for i in range(n)]

    for i in range(1, m+1):
        belt[order[i+2]-1].append(i)

    for i in range(n):
        if len(belt[i]) == 0:
            continue

        head[i] = belt[i][0]
        tail[i] = belt[i][-1]
        num[i] = len(belt[i])

        for j in range(len(belt[i])-1):
            next[belt[i][j]] = belt[i][j+1]
            prev[belt[i][j+1]] = belt[i][j]


# 2) ๋ฌผ๊ฑด ๋ชจ๋‘ ์˜ฎ๊ธฐ๊ธฐ
def move(order):
    src, dst = order[1] - 1, order[2] - 1

    # src์— ๋ฌผ๊ฑด์ด ์—†๋‹ค๋ฉด ๊ทธ๋Œ€๋กœ dst๋‚ด ๋ฌผ๊ฑด ์ˆ˜๊ฐ€ ๋‹ต์ด ๋จ 
    if num[src] == 0:
        print(num[dst])
        return
    
    # dst์— ๋ฌผ๊ฑด์ด ์—†๋‹ค๋ฉด ๊ทธ๋Œ€๋กœ ์˜ฎ๊ฒจ์คŒ 
    elif num[dst] == 0:
        head[dst] = head[src]
        tail[dst] = tail[src]

    else:
        dh = head[dst]
        head[dst] = head[src]
        st = tail[src]
        next[st] = dh
        prev[dh] = st
        
    head[src], tail[src] = 0, 0
    num[dst] += num[src]
    num[src] = 0

    print(num[dst])


# ํ•ด๋‹น ๋ฒจํŠธ์˜ head๋ฅผ ์ œ๊ฑฐํ•จ 
def remove(idx):
    # ํ•ด๋‹น ๋ฒจํŠธ๊ฐ€ ๋น„์–ด์žˆ์„ ๊ฒฝ์šฐ ๋ถˆ๊ฐ€๋Šฅํ•จ -> 0 ๋ฆฌํ„ด -> ๋’ค์˜ push ํ•จ์ˆ˜์—์„œ ์ด์–ด์ง 
    if num[idx] == 0:
        return 0

    # ํ•ด๋‹น ๋ฒจํŠธ ๋‚ด ์„ ๋ฌผ ๊ฐœ์ˆ˜๊ฐ€ 1๊ฐœ๋ผ๋ฉด -> head, tail ์ „๋ถ€ ์‚ญ์ œ 
    if num[idx] == 1:
        hid = head[idx]
        head[idx], tail[idx] = 0, 0
        num[idx] = 0
        return hid

    hid = head[idx]   # ์ œ๊ฑฐ๋  head๊ฐ’ 
    nh = next[hid]   # ๋ฐ”๋€ head๊ฐ’ 
    next[hid], prev[nh] = 0, 0
    num[idx] -= 1
    head[idx] = nh

    return hid


# ํ•ด๋‹น ๋ฒจํŠธ์— head๋ฅผ ์ถ”๊ฐ€ํ•จ 
def push(idx, nh):
    # ๋ถˆ๊ฐ€๋Šฅํ•  ๊ฒฝ์šฐ ์ง„ํ–‰ํ•˜์ง€ ์•Š์Œ 
    if nh == 0:
        return 

    # ํ•ด๋‹น ๋ฒจํŠธ๊ฐ€ ๋น„์–ด์žˆ์„ ๊ฒฝ์šฐ -> head, tail์ด ๋™์‹œ์— ์ถ”๊ฐ€๋จ
    if num[idx] == 0:
        head[idx], tail[idx] = nh, nh
        num[idx] = 1

    else:
        hid = head[idx]   # ์›๋ž˜์˜ head๊ฐ’ -> ์ถ”๊ฐ€ํ•œ ๋’ค์—๋Š” nh-hid์ˆœ์ด ๋จ 
        next[nh] = hid
        prev[hid] = nh
        head[idx] = nh
        num[idx] += 1


# 3) ์•ž ๋ฌผ๊ฑด๋งŒ ๊ต์ฒดํ•˜๊ธฐ
def change(order):
    src, dst = order[1] - 1, order[2] - 1

    sh = remove(src)
    dh = remove(dst)
    push(dst, sh)
    push(src, dh)

    print(num[dst])


# 4) ๋ฌผ๊ฑด ๋‚˜๋ˆ„๊ธฐ 
def divide(order):
    src, dst = order[1] - 1, order[2] - 1

    cnt = num[src]
    bid = []

    # src์—์„œ cnt//2๊ฐœ๋งŒํผ ์„ ๋ฌผ๋“ค์„ ๋นผ์คŒ 
    for _ in range(cnt//2):
        bid.append(remove(src))

    # ๊ฑฐ๊พธ๋กœ ๋’ค์ง‘์–ด์„œ ํ•˜๋‚˜์”ฉ dst์— ์„ ๋ฌผ๋“ค์„ ๋„ฃ์–ด์คŒ
    for i in range(len(bid)-1, -1, -1):
        push(dst, bid[i])

    print(num[dst])


# 5) ์„ ๋ฌผ ์ •๋ณด ์–ป๊ธฐ 
def gift(order):
    pnum = order[1]

    if prev[pnum] != 0:
        a = prev[pnum]
    else:
        a = -1

    if next[pnum] != 0:
        b = next[pnum]
    else:
        b = -1

    print(a + 2 * b)


# 6) ๋ฒจํŠธ ์ •๋ณด ์–ป๊ธฐ
def belt(order):
    bnum = order[1] - 1

    if head[bnum] != 0:
        a = head[bnum]
    else:
        a = -1

    if tail[bnum] != 0:
        b = tail[bnum]
    else:
        b = -1

    c = num[bnum]
    print(a + 2 * b + 3 * c)
        
           
for _ in range(q):
    order = list(map(int, input().split()))

    if order[0] == 100:
        build(order)            
    elif order[0] == 200:
        move(order)
    elif order[0] == 300:
        change(order)
    elif order[0] == 400:
        divide(order)
    elif order[0] == 500:
        gift(order)
    else:
        belt(order)

ใ„นใ…‡ ๋นก๊ตฌํ˜„
์‹œํ—˜์žฅ์—์„œ ๋ณด๋ฉด ๋ฉ˜๋ถ•์˜ฌ๋“ฏ..



3๏ธโƒฃ ๋ฐฐ์šด ์ 

์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ๋ฅผ ํ”ํžˆ ์งœ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ [prev, next] ์ด๋Ÿฐ ์‹์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๊ฒŒ ์•„๋‹ˆ๋ผ prev, next, head, tail, num ๋ฐฐ์—ด์„ ๊ฐ๊ฐ ๋งŒ๋“ค์–ด ์ฃผ๋Š” ๊ฒŒ ์ธ์ƒ์ ์ด์—ˆ๋‹ค
์‚ฌ์‹ค ์ฒ˜์Œ์— [prev, next]๋งŒ ์“ธ ๋•Œ๋Š” ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ์˜ ์ด์ ์ด ์•ˆ ๋ณด์ด๊ธด ํ–ˆ๋‹ค
โ€‹

1) ๊ณต์žฅ ์„ค๋ฆฝ -> ์ดˆ๊ธฐํ™” ๊ณผ์ •
โ€‹
2) ๋ฌผ๊ฑด ๋ชจ๋‘ ์˜ฎ๊ธฐ๊ธฐ
src๋ฒˆ์งธ ๋ฒจํŠธ์— ์žˆ๋Š” ์„ ๋ฌผ๋“ค์„ ๋ชจ๋‘ dst๋ฒˆ์งธ ๋ฒจํŠธ๋กœ ์˜ฎ๊น€ (head, tail, prev, next ๋ฆฌ์ŠคํŠธ ์‚ฌ์šฉ)
dst๋ฒˆ์งธ ๋ฒจํŠธ์— ์žˆ๋Š” ์„ ๋ฌผ๋“ค์˜ ๊ฐœ์ˆ˜ ์ถœ๋ ฅ (num ๋ฆฌ์ŠคํŠธ)
โ€‹
3) ์•ž ๋ฌผ๊ฑด๋งŒ ๊ต์ฒดํ•˜๊ธฐ
src๋ฒˆ์งธ ๋ฒจํŠธ์— ์žˆ๋Š” ๋งจ ์•ž ์„ ๋ฌผ๊ณผ dst๋ฒˆ์งธ ๋ฒจํŠธ์— ์žˆ๋Š” ๋งจ ์•ž ์„ ๋ฌผ์„ ๊ต์ฒด
dst๋ฒˆ์งธ ๋ฒจํŠธ์— ์žˆ๋Š” ์„ ๋ฌผ๋“ค์˜ ๊ฐœ์ˆ˜ ์ถœ๋ ฅ (num ๋ฆฌ์ŠคํŠธ)

๊ต์ฒด ์ž‘์—… -> ์‚ญ์ œ, ์ถ”๊ฐ€ ์ž‘์—… ํ•„์š”
โ€‹
4) ๋ฌผ๊ฑด ๋‚˜๋ˆ„๊ธฐ
src๋ฒˆ์งธ ๋ฒจํŠธ์—์„œ ๋งจ์•ž๋ถ€ํ„ฐ cnt//2๋ฒˆ์งธ ์„ ๋ฌผ๊นŒ์ง€ dst๋ฒˆ์งธ ๋ฒจํŠธ๋กœ ์˜ฎ๊น€
dst๋ฒˆ์งธ ๋ฒจํŠธ์— ์žˆ๋Š” ์„ ๋ฌผ๋“ค์˜ ๊ฐœ์ˆ˜ ์ถœ๋ ฅ (num ๋ฆฌ์ŠคํŠธ)

์ฒ˜์Œ๋ถ€ํ„ฐ cnt//2๋ฒˆ์งธ๊นŒ์ง€ ์„ ๋ฌผ ๋นผ์คŒ -> ์‚ญ์ œ ์ž‘์—…
๋บ€ ์„ ๋ฌผ์„ dst๋ฒˆ์งธ ๋ฒจํŠธ์— ๋”ํ•ด์คŒ -> ์ถ”๊ฐ€ ์ž‘์—…

-> 3, 4๋ฒˆ์—์„œ ๊ณตํ†ต์œผ๋กœ ์ถ”๊ฐ€/์‚ญ์ œ ์ž‘์—…์„ ํ•˜๋ฏ€๋กœ ์ถ”๊ฐ€/์‚ญ์ œ ํ•จ์ˆ˜๋ฅผ ๋”ฐ๋กœ ๋งŒ๋“ค์–ด์คŒ
โ€‹
5) ์„ ๋ฌผ ์ •๋ณด ์–ป๊ธฐ
p_num ์„ ๋ฌผ์˜ ์•ž ์„ ๋ฌผ์„ a(prev ๋ฆฌ์ŠคํŠธ), ๋’ค ์„ ๋ฌผ์„ b(next ๋ฆฌ์ŠคํŠธ)๋ผ๊ณ  ํ•  ๋•Œ, a + 2 b๊ฐ’์„ ์ถœ๋ ฅํ•จ
โ€‹
6) ๋ฒจํŠธ ์ •๋ณด ์–ป๊ธฐ
b_num ๋ฒจํŠธ์˜ ๋งจ ์•ž์— ์žˆ๋Š” ์„ ๋ฌผ ๋ฒˆํ˜ธ๋ฅผ a(head ๋ฆฌ์ŠคํŠธ), ๋งจ ๋’ค์— ์žˆ๋Š” ์„ ๋ฌผ ๋ฒˆํ˜ธ๋ฅผ b(tail ๋ฆฌ์ŠคํŠธ)๋ผ๊ณ  ํ•  ๋•Œ, a + 2
b + 3 * c๋ฅผ ์ถœ๋ ฅํ•จ

โ€‹
์ฝ”๋“œ ์ดˆ๊ธฐ ์„ค๊ณ„๊ฐ€ ์ค‘์š”ํ–ˆ๋˜ ๋ฌธ์ œ

profile
๐Ÿฅ๐Ÿ‘ฉโ€๐Ÿ’ป๐Ÿ’ฐ

0๊ฐœ์˜ ๋Œ“๊ธ€