๐Ÿ”‘ CS/์ฝ”๋”ฉํ…Œ์ŠคํŠธ

[๋ฐฑ์ค€ 1697๋ฒˆ] ์ˆจ๋ฐ”๊ผญ์งˆ (python/ํŒŒ์ด์ฌ)

๋ณต๋งŒ 2022. 6. 30. 14:30

๊ทธ๋ž˜ํ”„ ํƒ์ƒ‰ ๋ฌธ์ œ์ธ๋ฐ ์ˆ˜ํ•™์ ์œผ๋กœ ๋จธ๋ฆฌ๋ฅผ ์ž˜ ๊ตด๋ ค์„œ ์ตœ๋Œ€ํ•œ ํšจ์œจ์ ์œผ๋กœ ํƒ์ƒ‰ํ•ด์•ผ ํ•˜๋Š” ๋ฌธ์ œ์˜€๋‹ค. ๊ณ„์† ์‹œ๊ฐ„์ดˆ๊ณผ๊ฐ€ ๋– ์„œ ์ด๊ฒƒ์ €๊ฒƒ ๊ทœ์น™์„ ์ถ”๊ฐ€ํ•˜๋‹ค๊ฐ€ ๋ฌธ์ œ๋ฅผ ๋ฐœ๊ฒฌํ•˜๊ณ  ์„ฑ๊ณตํ–ˆ๋‹ค.

 

๐ŸŒผ ๋ฌธ์ œ ๋งํฌ

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

 

1697๋ฒˆ: ์ˆจ๋ฐ”๊ผญ์งˆ

์ˆ˜๋นˆ์ด๋Š” ๋™์ƒ๊ณผ ์ˆจ๋ฐ”๊ผญ์งˆ์„ ํ•˜๊ณ  ์žˆ๋‹ค. ์ˆ˜๋นˆ์ด๋Š” ํ˜„์žฌ ์  N(0 ≤ N ≤ 100,000)์— ์žˆ๊ณ , ๋™์ƒ์€ ์  K(0 ≤ K ≤ 100,000)์— ์žˆ๋‹ค. ์ˆ˜๋นˆ์ด๋Š” ๊ฑท๊ฑฐ๋‚˜ ์ˆœ๊ฐ„์ด๋™์„ ํ•  ์ˆ˜ ์žˆ๋‹ค. ๋งŒ์•ฝ, ์ˆ˜๋นˆ์ด์˜ ์œ„์น˜๊ฐ€ X์ผ

www.acmicpc.net

  • ํ‹ฐ์–ด: ์‹ค๋ฒ„ I
  • ๋ถ„๋ฅ˜: ๊ทธ๋ž˜ํ”„ ์ด๋ก , ๊ทธ๋ž˜ํ”„ ํƒ์ƒ‰, ๋„ˆ๋น„ ์šฐ์„  ํƒ์ƒ‰

 

 

โ— TRIAL 1.

๋”๋ณด๊ธฐ
์ฝ”๋“œ
from collections import deque

walk_left = lambda x: x-1
walk_right = lambda x: x+1
jump = lambda x:2*x

def actions(v, end):
    if v > end:
        return [walk_left]
    else:
        return [walk_left, walk_right, jump]

def bfs(start, end):
    visited = [start]
    queue = deque([(0, start)])
    while queue:
        curr_time, curr_v = queue.popleft()
        if curr_v == end:
            return curr_time
        for action in actions(curr_v, end):
            new_v = action(curr_v)
            if 0 < new_v and new_v not in visited:
                visited.append(new_v)
                queue.append((curr_time+1, new_v))

N, K = map(int, input().split())

print(bfs(N, K))

 

ํ‹€๋ฆฐ ์›์ธ

 

์‹œ๊ฐ„์ดˆ๊ณผ. 

 

 

โ— TRIAL 2.

๋”๋ณด๊ธฐ
์ฝ”๋“œ
from collections import deque

walk_left = lambda x: x-1
walk_right = lambda x: x+1
jump = lambda x:2*x

def actions(v, end):
    if v == 0:
        return [walk_right]
    if v > end:
        return [walk_left]
    elif 2*end <= 3*v:
        return [walk_left, walk_right]
    else:
        return [walk_left, walk_right, jump]

def bfs(start, end):
    if end < start:
        return start - end
    visited = [start]
    queue = deque([(0, start)])
    while queue:
        curr_time, curr_v = queue.popleft()
        if curr_v == end:
            return curr_time
        for action in actions(curr_v, end):
            new_v = action(curr_v)
            if new_v not in visited:
                visited.append(new_v)
                queue.append((curr_time+1, new_v))

N, K = map(int, input().split())

print(bfs(N, K))

 

์ˆ˜์ •ํ•œ ๋ถ€๋ถ„

 

- ๊ฐ node์—์„œ action์˜ ๊ฐฏ์ˆ˜์— ๋”ฐ๋ผ ๊ทธ๋ž˜ํ”„์˜ ํฌ๊ธฐ๊ฐ€ ๋งค์šฐ ๋Š˜์–ด๋‚˜๊ธฐ ๋•Œ๋ฌธ์— action์˜ ๊ฐฏ์ˆ˜๋ฅผ ์ตœ์†Œํ™”ํ•˜๊ธฐ ์œ„ํ•ด ์—ฌ๋Ÿฌ ์กฐ๊ฑด์„ ์ถ”๊ฐ€ํ•จ.

- ํ˜„์žฌ ์œ„์น˜๊ฐ€ 0์ผ ๊ฒฝ์šฐ ์˜ค๋ฅธ์ชฝ์œผ๋กœ๋งŒ ์ด๋™ํ•˜๊ฒŒ ํ•˜๊ณ , ์ˆœ๊ฐ„์ด๋™(2๋ฐฐ) ํ–ˆ์„ ๋•Œ end์˜ 2๋ฐฐ๋ฅผ ๋„˜์–ด๊ฐ€๋Š” ๊ฒฝ์šฐ์—๋Š” jump๋ฅผ ํ•˜์ง€ ์•Š๋„๋ก ํ•จ.

 

ํ‹€๋ฆฐ ์›์ธ

 

์‹œ๊ฐ„์ดˆ๊ณผ.

 

 

โ— TRIAL 3.

๋”๋ณด๊ธฐ
์ฝ”๋“œ
from collections import deque

walk_left = lambda x: x-1
walk_right = lambda x: x+1
jump = lambda x:2*x

def actions(v, end):
    if v == 0:
        return [walk_right]
    else:
        return [walk_left, walk_right, jump]

def bfs(start, end):
    if end <= start:
        return start - end
    times = set()
    visited = [start]
    queue = deque([(0, start)])
    while queue:
        curr_time, curr_v = queue.popleft()
        new_time = curr_time + 1
        for action in actions(curr_v, end):
            new_v = action(curr_v)
            if new_v not in visited:
                visited.append(new_v)
                if new_v == end:
                    times.add(new_time)
                    return min(times)
                elif new_v > end:
                    times.add(new_time + new_v - end)
                else:
                    queue.append((new_time, new_v))

N, K = map(int, input().split())

print(bfs(N, K))

 

์ˆ˜์ •ํ•œ ๋ถ€๋ถ„

 

- ํ˜„์žฌ ์œ„์น˜๊ฐ€ end๋ณด๋‹ค ์˜ค๋ฅธ์ชฝ์— ์žˆ๋Š” ๊ฒฝ์šฐ, ์™ผ์ชฝ์œผ๋กœ ์ด๋™ํ•˜๋Š” ์„ ํƒ์ง€๋ฐ–์— ์—†๊ธฐ ๋•Œ๋ฌธ์— ํ•ด๋‹น ๊ฒฝ์šฐ ํƒ์ƒ‰์„ ์ข…๋ฃŒํ•˜๊ณ  curr_v-end ๋งŒํผ์˜ ์‹œ๊ฐ„์„ curr_time์— ๋”ํ•œ ๊ฐ’์„ times set์— ๊ธฐ๋กํ•จ. ๋ชฉํ‘œ๊ฐ’์„ ์ฐพ์•˜์„ ๋•Œ, times set์˜ ๊ฐ’๋“ค๊ณผ ๋น„๊ตํ•˜์—ฌ ๊ฐ€์žฅ ์ž‘์€ ๊ฐ’์„ return ํ•จ.

- queue์—์„œ pop ํ•œ ๊ฐ’๋“ค์— ๋Œ€ํ•ด ๊ฒ€์‚ฌ๋ฅผ ์ง„ํ–‰ํ•˜์ง€ ์•Š๊ณ , new_v๋ฅผ ๊ตฌํ•œ ์งํ›„์— ๊ฒ€์‚ฌ๋ฅผ ์ง„ํ–‰ํ•จ. ์ฆ‰ node๋ฅผ ๋ฐฉ๋ฌธํ•œ ์งํ›„์— ํ•ด๋‹น node์˜ ๊ฐ’์„ end์™€ ๋น„๊ตํ•œ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜์ง€ ์•Š๊ณ  queue์—์„œ popํ•œ ๋‹ค์Œ์— ๊ฒ€์‚ฌ๋ฅผ ์ง„ํ–‰ํ•˜๋ฉด, node๊ฐ€ end์— ๋„๋‹ฌํ–ˆ์–ด๋„ ํ•ด๋‹น depth์˜ node๋ฅผ ๋ชจ๋‘ ๊ฒ€์‚ฌํ•œ ์ดํ›„์— ํ”„๋กœ๊ทธ๋žจ์ด ์ข…๋ฃŒ๋˜์–ด ๋น„ํšจ์œจ์ ์ด๋‹ค.

 

ํ‹€๋ฆฐ ์›์ธ

 

์‹œ๊ฐ„์ดˆ๊ณผ. ์กฐ๊ฑด์„ ์ด๊ฒƒ์ €๊ฒƒ ์ถ”๊ฐ€ํ•ด๋ดค์ง€๋งŒ ์›์ธ์€ visited์— ์žˆ์—ˆ๋‹ค. ๋‚˜๋Š” visited๋ฅผ ๋นˆ array๋กœ ๋งŒ๋“ค๊ณ , ๋ฐฉ๋ฌธํ•œ node๋ฅผ ์ฐจ๋ก€๋Œ€๋กœ appendํ•˜๊ณ  node๋ฅผ ๋ฐฉ๋ฌธํ•  ๋•Œ๋งˆ๋‹ค ํ•ด๋‹น node๊ฐ€ visited์— ์žˆ๋Š”์ง€ ๊ฒ€์‚ฌํ–ˆ๋Š”๋ฐ, ์ด๋Š” array์˜ ๋ชจ๋“  ๊ฐ’์„ ํƒ์ƒ‰ํ•˜๊ธฐ ๋•Œ๋ฌธ์— O(n) ์‹œ๊ฐ„์ด ์†Œ์š”๋จ.

์ด๋ ‡๊ฒŒ ํ•˜์ง€ ๋ง๊ณ  False๋กœ ๊ตฌ์„ฑ๋œ array๋ฅผ ๋งŒ๋“ค๊ณ  ๋ฐฉ๋ฌธํ–ˆ์„ ๋•Œ๋งˆ๋‹ค True๋กœ ๋ฐ”๊ฟ”์ฃผ์–ด node๋ฅผ ๋ฐฉ๋ฌธํ•  ๋•Œ๋งˆ๋‹ค ํ•ด๋‹น ๊ฐ’์ด True/False์ธ์ง€ ๊ฒ€์‚ฌํ•˜๊ฒŒ ํ–ˆ์–ด์•ผ ํ•œ๋‹ค.

 

 

๐Ÿ’ก Solution

์ฝ”๋“œ
from collections import deque

walk_left = lambda x: x-1
walk_right = lambda x: x+1
jump = lambda x:2*x

def actions(v, end):
    if v == 0:
        return [walk_right]
    else:
        return [walk_left, walk_right, jump]

def bfs(start, end, visited):
    if end <= start:
        return start - end
    times = set()
    visited[start] = True
    queue = deque([(0, start)])
    while queue:
        curr_time, curr_v = queue.popleft()
        new_time = curr_time + 1
        for action in actions(curr_v, end):
            new_v = action(curr_v)
            if not visited[new_v]:
                visited[new_v] = True
                if new_v == end:
                    times.add(new_time)
                    return min(times)
                elif new_v > end:
                    times.add(new_time + new_v - end)
                else:
                    queue.append((new_time, new_v))

N, K = map(int, input().split())

visited = [False] * (2*K)
print(bfs(N, K, visited))

 

์ฝ”๋“œ ์„ค๋ช…
  • ํ˜„์žฌ ์œ„์น˜์—์„œ ์™ผ์ชฝ์œผ๋กœ ์ด๋™/์˜ค๋ฅธ์ชฝ์œผ๋กœ ์ด๋™/์ˆœ๊ฐ„์ด๋™(2๋ฐฐ) ๋กœ ๊ฐ€๋Š” ์œ„์น˜๋“ค์„ bfs๋กœ ํƒ์ƒ‰ํ•œ๋‹ค.
  • ๋งŒ์•ฝ ํ˜„์žฌ ์œ„์น˜๊ฐ€ end ๋ณด๋‹ค ์˜ค๋ฅธ์ชฝ์— ์žˆ์œผ๋ฉด, ์™ผ์ชฝ์œผ๋กœ ์ด๋™๋ฐ–์— ์„ ํƒ์ง€๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์— ํ•ด๋‹น ๊ฐ€์ง€์˜ ํƒ์ƒ‰์„ ์ข…๋ฃŒํ•˜๊ณ  ๋‚จ์€ ์‹œ๊ฐ„์„ ๊ณ„์‚ฐํ•˜์—ฌ times set์— ์ถ”๊ฐ€ํ•œ๋‹ค.
  • ๋งŒ์•ฝ ํ˜„์žฌ ์œ„์น˜๊ฐ€ end์— ๋„๋‹ฌํ•˜๋ฉด ๋ชจ๋“  ํƒ์ƒ‰์„ ์ข…๋ฃŒํ•˜๊ณ , times set์˜ ์‹œ๊ฐ„๋“ค๊ณผ ํ˜„์žฌ ์‹œ๊ฐ„์„ ๋น„๊ตํ•ด ๊ฐ€์ž‘ ์ž‘์€ ๊ฐ’์„ returnํ•œ๋‹ค.

 

์ฃผ์˜ํ•  ์ 
  • ๋ฐฉ๋ฌธ์—ฌ๋ถ€๋ฅผ ๋‹ด์€ visited array๋Š” v in visited๋กœ ๊ฒ€์‚ฌํ•˜๋ฉด visited์˜ ๋ชจ๋“  ์›์†Œ๋ฅผ ๋‹ค ๊ฒ€์‚ฌํ•ดํ– ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์˜ค๋ž˜ ๊ฑธ๋ฆฐ๋‹ค. ์ฒ˜์Œ์— False๋กœ ๊ตฌ์„ฑ๋œ array๋ฅผ ์„ ์–ธํ•˜๊ณ  ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ํ•ด์•ผ ํ•จ.
  • BFS์—์„œ queue์— ๊ฐ’์„ ๋„ฃ๊ธฐ ์ „์— ์ข…๋ฃŒ ์—ฌ๋ถ€ ๊ฒ€์‚ฌ๋ฅผ ํ•ด์•ผ ํ•œ๋‹ค. queue์—์„œ pop ํ•œ ์ดํ›„์— ๊ฒ€์‚ฌํ•˜๋ฉด, ์กฐ๊ฑด์ด ๋‹ฌ์„ฑ๋œ ์ดํ›„์—๋„ ๊ฐ™์€ depth์˜ node๋“ค์„ ๋ชจ๋‘ ๋ฐฉ๋ฌธํ•˜๊ฒŒ ๋˜๊ธฐ ๋•Œ๋ฌธ์— ๋น„ํšจ์œจ์ ์ด๋‹ค.
๋ฐ˜์‘ํ˜•