๐Ÿ’ซ ETC/Problem Solving

[SWEA] 1206. [S/W ๋ฌธ์ œํ•ด๊ฒฐ ๊ธฐ๋ณธ] 2์ผ์ฐจ - ์ตœ๋Œ€ ์ƒ๊ธˆ (DFS)

ming412 2023. 11. 16. 14:38

โœ๏ธ ๋ฌธ์ œ ์š”์•ฝ

https://swexpertacademy.com/main/code/problem/problemDetail.do?problemLevel=3&contestProbId=AV15Khn6AN0CFAYD&categoryId=AV15Khn6AN0CFAYD&categoryType=CODE

 

SW Expert Academy

SW ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์—ญ๋Ÿ‰ ๊ฐ•ํ™”์— ๋„์›€์ด ๋˜๋Š” ๋‹ค์–‘ํ•œ ํ•™์Šต ์ปจํ…์ธ ๋ฅผ ํ™•์ธํ•˜์„ธ์š”!

swexpertacademy.com

 

์ˆซ์žํŒ๊ณผ ๊ตํ™˜ ํšŸ์ˆ˜๊ฐ€ ์ฃผ์–ด์ง„๋‹ค. ์ฃผ์–ด์ง„ ์ˆซ์žํŒ๋“ค ์ค‘ ๋‘ ์ˆ˜๋ฅผ ์„ ํƒํ•ด์„œ ์ •ํ•ด์ง„ ํšŸ์ˆ˜๋งŒํผ ๊ตํ™˜ํ•ด์•ผ ํ•  ๋•Œ, ๊ฐ€์žฅ ํฐ ์ˆ˜๋ฅผ ๋งŒ๋“ค์–ด๋ผ.

 

 

๐Ÿ’ช ๋ฌด์‹ํ•˜๊ฒŒ ํ’€๊ธฐ

๊ตฌํ˜„์ด ์–ด๋ ต๋‹ค๊ธฐ ๋ณด๋‹ค๋Š” ์ƒ๊ฐํ•ด์•ผ ํ•˜๋Š” ์กฐ๊ฑด์ด ๊นŒ๋‹ค๋กœ์šด ๋ฌธ์ œ์˜€๋‹ค. ๐Ÿฅฒ

 

1. for๋ฌธ์œผ๋กœ ์ƒ๊ธˆ(`price`)์˜ ๊ฐ ์ž๋ฆฌ๋ฅผ ์ˆœํšŒํ•˜๋ฉด์„œ, ๋‚˜(`price[i]`) ์ดํ›„์— ๋‚˜๋ณด๋‹ค ํฐ max๊ฐ€ ์žˆ์œผ๋ฉด ๋‚˜์™€ ๊ตํ™˜ํ•  ๊ฒƒ์ด๋‹ค.

    1-1. ์ด๋•Œ, ๊ฐ’์ด ๊ฐ™์€ max๊ฐ€ ๋‘ ๊ฐœ ์ด์ƒ ์žˆ์œผ๋ฉด์„œ && ๋‚ด ๋’ค์— ๋‚˜๋ณด๋‹ค ์ž‘์€ ๊ฐ’์ด ์žˆ์œผ๋ฉด -> ๋‚˜๋Š” ๋งจ ์˜ค๋ฅธ์ชฝ max๊ฐ€ ์•„๋‹Œ, ๋งจ ์˜ค๋ฅธ์ชฝ max์—์„œ ํ•œ ์นธ ์•ž์˜ max์™€ ๊ตํ™˜ํ•ด์•ผ ํ•œ๋‹ค. โญ๏ธ

    1-2. ๋งŒ์•ฝ max๊ฐ€ ํ•œ ๊ฐœ์ด๊ฑฐ๋‚˜ || ๋‘ ๊ฐœ ์ด์ƒ์ด๋ผ๋„ ๋‚ด ๋’ค์— ๋‚˜๋ณด๋‹ค ์ž‘์€ ๊ฐ’์ด ์—†๋‹ค๋ฉด -> ๋‚˜์™€ ๋งจ ์˜ค๋ฅธ์ชฝ max๋ฅผ ๊ตํ™˜ํ•œ๋‹ค.

 

2. for๋ฌธ์„ ๋‹ค ๋Œ์•˜๋Š”๋ฐ ๊ตํ™˜ ํšŸ์ˆ˜(`N`)๊ฐ€ ๋‚จ์•˜๋‹ค๋ฉด

    2-1. ์ƒ๊ธˆ(`price`)์— ๊ฐ™์€ ์ˆ˜๊ฐ€ ๋‘ ๊ฐœ ์ด์ƒ ์žˆ๋‹ค๋ฉด -> ๊ทธ๋Œ€๋กœ ์ข…๋ฃŒํ•œ๋‹ค. (๊ฐ™์€ ์ˆ˜๋ผ๋ฆฌ ๊ณ„์† ๊ตํ™˜ํ•ด์„œ ๊ตํ™˜ ํšŸ์ˆ˜๋ฅผ ์†Œ๋ชจํ•˜๋ฉด ๋˜๊ธฐ ๋•Œ๋ฌธ)

    2-2. ์ƒ๊ธˆ์ด ๋ชจ๋‘ ๋‹ค๋ฅธ ์ˆ˜๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ๋‹ค๋ฉด

        2-2-1. ๊ตํ™˜ ํšŸ์ˆ˜(`N`)๊ฐ€ ์ง์ˆ˜๊ฐœ ๋‚จ์•˜๋‹ค๋ฉด -> ๊ทธ๋Œ€๋กœ ์ข…๋ฃŒํ•œ๋‹ค. (์•„๋ฌด๊ฑฐ๋‚˜ ๋‘ ๊ฐœ ๊ตํ™˜ํ•˜๊ณ  ๋‹ค์‹œ ์›์ƒ๋ณต๊ท€ํ•˜๋ฉด ๋˜๊ธฐ ๋•Œ๋ฌธ)

        2-2-2. ๊ตํ™˜ ํšŸ์ˆ˜(`N`)๊ฐ€ ํ™€์ˆ˜๊ฐœ ๋‚จ์•˜๋‹ค๋ฉด -> ์ œ์ผ ์˜ค๋ฅธ์ชฝ ๋‘ ์ž๋ฆฌ๋ฅผ ํ•œ ๋ฒˆ๋งŒ ๊ตํ™˜ํ•œ๋‹ค. (์ง์ˆ˜๋ฒˆ์€ ์›์ƒ๋ณต๊ท€ํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ํ–ˆ๋‹ค. ๋”ฐ๋ผ์„œ, ํ™€์ˆ˜๋ฒˆ์€ ์ง์ˆ˜๋ฒˆ + 1 ์ด๋ฏ€๋กœ ํ•œ ๋ฒˆ๋งŒ ๊ตํ™˜ํ•˜๋ฉด ๋œ๋‹ค. ๊ตํ™˜ ํšŸ์ˆ˜๋ฅผ ๋ชจ๋‘ ์†Œ๋ชจํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฌด์กฐ๊ฑด ํ•œ ๋ฒˆ์€ ๊ตํ™˜ํ•ด์•ผ ํ•œ๋‹ค. ๋”ฐ๋ผ์„œ, ์ˆ˜๊ฐ€ ์ตœ์†Œํ•œ์œผ๋กœ ์ž‘์•„์ง€๋„๋ก ๋งจ ์˜ค๋ฅธ์ชฝ ๋‘ ์ž๋ฆฌ๋ฅผ ๊ตํ™˜ํ•˜์ž.)

import sys
sys.stdin = open("input.txt", "r")
sys.stdout = open("output.txt", "w")

def find_all_max_index(start_idx):
    mx = -1e9
    max_idx = []
    for i in range(start_idx, len(price)):
        if price[i] > mx:
            mx = price[i] # ์ตœ๋Œ“๊ฐ’ ๊ฐฑ์‹ 
            max_idx = [i]
        elif price[i] == mx:
            max_idx.append(i)
    return max_idx # ๋ชจ๋“  ์ตœ๋Œ“๊ฐ’ ์ธ๋ฑ์Šค

# lst์— ๊ณตํ†ต ์›์†Œ 2๊ฐœ ์ด์ƒ ์กด์žฌํ•˜๋Š”์ง€ ํ™•์ธ
def is_exist_duplicated_value(lst):
    visited = [0] * 10
    for x in lst:
        visited[x] += 1
        if visited[x] > 1: return True
    return False

# ๋‚˜ ์ดํ›„์— ๋‚˜๋ณด๋‹ค ์ž‘์€ ์›์†Œ ์žˆ๋Š”์ง€ ํ™•์ธ
def is_exist_smaller_than_me(start_idx, target):
    for i in range(start_idx, len(price)):
        if price[i] < target: return True
    return False

if __name__ == '__main__':
    T = int(input())
    for test_case in range(1, T+1):

        price, N = map(int, input().split())
        price = list(map(int, str(price)))

        for i in range(len(price)):
            # ๋‚˜ ์ดํ›„ ์›์†Œ๋“ค ์ค‘ max๊ฐ€ ๋‚˜๋ณด๋‹ค ํฌ๋ฉด ๋‚˜์™€ ๋ณ€๊ฒฝํ• ๊ฑด๋ฐ
            if len(find_all_max_index(i+1)) > 0 and price[i] < price[find_all_max_index(i+1)[0]]:
                # 1) ๊ฐ™์€ max๊ฐ€ ๋‘ ๊ฐœ ์ด์ƒ ์žˆ์œผ๋ฉด์„œ, ๋‚ด ๋’ค์— ๋‚˜๋ณด๋‹ค ์ž‘์€ ๊ฐ’ ์žˆ์œผ๋ฉด -> ๋‚˜๋Š” ๋งˆ์ง€๋ง‰ ํ•œ ์นธ ์™ผ์ชฝ๊ณผ ๊ตํ™˜ (๋งˆ์ง€๋ง‰ ๋ง๊ณ )
                if len(find_all_max_index(i+1)) >= 2 and is_exist_smaller_than_me(i+1, price[i]):
                    price[i], price[find_all_max_index(i+1)[-2]] = price[find_all_max_index(i+1)[-2]], price[i]
                else: # 2) ์•„๋‹ˆ๋ผ๋ฉด ๋‚˜์™€ ๋งˆ์ง€๋ง‰ ๊ตํ™˜
                    price[i], price[find_all_max_index(i + 1)[-1]] = price[find_all_max_index(i + 1)[-1]], price[i]
                N -= 1
                if N == 0: break

        # N(๊ตํ™˜ ํšŸ์ˆ˜)์ด ๋‚จ์•˜๋‹ค๋ฉด
        if N > 0 and not is_exist_duplicated_value(price) and N % 2 == 1:
            # ์–ด์ฉ” ์ˆ˜ ์—†์ด ์ œ์ผ ์˜ค๋ฅธ์ชฝ ๋‘ ์ž๋ฆฌ ๋ณ€๊ฒฝ
            price[-1], price[-2] = price[-2], price[-1]

        print('#{}'.format(test_case), end=' ')
        print(*price, sep='')

 

โœจ ์šฐ์•„ํ•˜๊ฒŒ ํ’€๊ธฐ (DFS)

DFS๋ฅผ ์ด์šฉํ•ด์„œ ์™„์ „ํƒ์ƒ‰์œผ๋กœ ํ’€ ์ˆ˜๋„ ์žˆ๋‹ค.

๋ชจ๋“  ๊ฒฝ์šฐ์˜ ์ˆ˜๋ฅผ ๋‹ค ์™„์ „ํƒ์ƒ‰ํ•˜๊ฒŒ ๋˜๋ฉด 15^10๊นŒ์ง€์˜ ๊ฒฝ์šฐ์˜ ์ˆ˜๊ฐ€ ๋‚˜์˜ค๊ธฐ ๋•Œ๋ฌธ์— โญ๏ธ ๊ฐ€์ง€์น˜๊ธฐ๊ฐ€ ์ค‘์š”ํ•˜๋‹ค!

 

1. ์šฐ์„  ์ƒ๊ธˆ(`price`)์„ ์ž…๋ ฅ ๋ฐ›์€ ๋’ค, ์ƒ๊ธˆ์˜ ์ž๋ฆฌ์ˆ˜๋งŒํผ `index` ๋ฆฌ์ŠคํŠธ๋ฅผ ์ƒ์„ฑํ•ด๋†“์ž. (DFS ํ•  ๋•Œ `combinations()` ๋ฉ”์„œ๋“œ๋ฅผ ์ด์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ์ด๋‹ค.)

 

2. ์ด์ œ DFS๋ฅผ ํ†ตํ•ด ๋ชจ๋“  ๊ฒฝ์šฐ์˜ ์ˆ˜๋ฅผ ํƒ์ƒ‰ํ•œ๋‹ค.

 

๊ตํ™˜ ํšŸ์ˆ˜๊ฐ€ `N`์ด๊ธฐ ๋•Œ๋ฌธ์—, Level(`L`)์ด N์ด ๋  ๋•Œ ์ตœ๋Œ“๊ฐ’(`mx`)์„ ๊ฐฑ์‹ ํ•œ๋‹ค. (์˜ˆ๋ฅผ ๋“ค์–ด `price` = [1,2,3] ์ด๋ผ๋ฉด `int(''.join(map(str, price)))`๋Š” 123(๋ฐฑ์ด์‹ญ์‚ผ)์ด ๋œ๋‹ค.)

 

๊ทธ๋ฆฌ๊ณ  ์•„๊นŒ ์ƒ์„ฑํ•ด๋†“์€ `index` ๋ฆฌ์ŠคํŠธ ์ค‘ ์ˆœ์„œ ์—†์ด(combination) ๋‘ ๊ฐœ๋ฅผ ๋ฝ‘๋Š”๋‹ค. (์ด๋•Œ ๋ฝ‘์€ ์ˆ˜๋Š” price์˜ '์ธ๋ฑ์Šค'์ด๋‹ค.)

 

๊ทธ๋ฆฌ๊ณ  ๋Ÿฌํ”„ํ•˜๊ฒŒ๋Š” ๋ฝ‘์€ ๋‘ ์ˆ˜๋ฅผ ๊ตํ™˜ํ•œ๋’ค ๋‹ค์Œ DFS(`DFS(L+1)`)๋ฅผ ํ˜ธ์ถœํ•˜๊ณ , ์ด๋•Œ ๊ตํ™˜ํ•œ ๋‘ ์ˆ˜๋ฅผ ๋‹ค์‹œ ์›๋ž˜๋Œ€๋กœ ๋Œ๋ ค๋†“์•„์•ผํ•˜๊ธฐ ๋•Œ๋ฌธ์— DFS ํ˜ธ์ถœ ์ดํ›„์— ํ•œ๋ฒˆ ๋” ๊ตํ™˜ํ•ด๋†“์œผ๋ฉด ๋œ๋‹ค. (ํ•˜์ง€๋งŒ ๋‹ค์Œ DFS๋ฅผ ํ˜ธ์ถœํ•˜๊ธฐ ์ „์— '๊ฐ€์ง€์น˜๊ธฐ'๋ฅผ ํ•ด์•ผ ์‹œ๊ฐ„์ดˆ๊ณผ๊ฐ€ ์•ˆ๋‚œ๋‹ค!)

 

๊ฐ€์ง€์น˜๊ธฐ๋ฅผ ์–ด๋–ค ๊ธฐ์ค€์œผ๋กœ ํ• ๊นŒโ“ 
์ˆซ์ž์™€ ๊ทธ ๋•Œ์˜ ๋ ˆ๋ฒจ์„ `visited` ๋ฐฐ์—ด์— ๋‹ด์•„๋†“์œผ๋ฉด ๋œ๋‹คโ—๏ธ (์ด๋•Œ ๋งํ•˜๋Š” ๋ ˆ๋ฒจ์€ '๋ช‡ ๋ฒˆ์งธ ๊ตํ™˜์ธ์ง€'๋ฅผ ์˜๋ฏธํ•œ๋‹ค.)

์˜ˆ๋ฅผ ๋“ค์–ด, [3,2,8,8,8]์ด๋ผ๋Š” ์ˆซ์žํŒ์ด ์ฃผ์–ด์กŒ์„ ๋•Œ,
์ฒซ ๋ฒˆ์งธ ๊ตํ™˜์—์„œ 2๋ฒˆ์ธ๋ฑ์Šค <-> 3๋ฒˆ ์ธ๋ฑ์Šค๋ฅผ ๊ตํ™˜ํ–ˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜์ž. ๊ทธ๋Ÿผ `visited`์— `(1, 32888)`์„ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์ด๋‹ค.
๋‘ ๋ฒˆ์งธ ๊ตํ™˜์—์„œ ๋˜ 2๋ฒˆ ์ธ๋ฑ์Šค <-> 3๋ฒˆ ์ธ๋ฑ์Šค๋ฅผ ๊ตํ™˜ํ–ˆ๋‹ค๋ฉด, `visited`์— `(2, 32888)`์„ ์ถ”๊ฐ€ํ•œ๋‹ค.

์ค‘์š”ํ•œ ๊ฒƒ์€, ์ˆ˜๊ฐ€ ๊ฐ™๋”๋ผ๋„ ๊ทธ๊ฒŒ ๋ช‡ ๋ฒˆ์งธ ๊ตํ™˜(=๋ ˆ๋ฒจ)์ธ์ง€์— ๋”ฐ๋ผ ์˜๋ฏธ๊ฐ€ ๋‹ค๋ฅด๋‹ˆ, `visited`์— ์ˆ˜์™€ ๋ ˆ๋ฒจ์„ ๊ผญ ํ•จ๊ป˜ ์ €์žฅํ•ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.

๊ทธ๋ฆฌ๊ณ  DFS๋ฅผ ํ˜ธ์ถœํ•˜๊ธฐ ์ „์— ํ•ด๋‹น (๋ ˆ๋ฒจ, ์ˆ˜)๊ฐ€ `visited`์— ์žˆ๋Š”์ง€ ํ™•์ธํ•œ๋‹ค. `visited`์— ์ด๋ฏธ ์กด์žฌํ•œ๋‹ค๋ฉด ๋” ์ด์ƒ ๊ฐˆ ํ•„์š”๊ฐ€ ์—†๋Š” ๊ธธ์ธ ๊ฒƒ์ด๋‹ค. (์ด์ „์— ์ด๋ฏธ ๊ฐ™์€๊ฑธ ํ–ˆ์—ˆ๊ธฐ ๋•Œ๋ฌธ!) 

 

from itertools import combinations

def DFS(L):
    global mx
    if L == N:
        mx = max(mx, int(''.join(map(str, price))))
        return
    for a, b in combinations(index, 2):
        price[a], price[b] = price[b], price[a]
        num = int(''.join(map(str, price))) # ๊ฐ€์ง€์น˜๊ธฐ๋ฅผ ์œ„ํ•ด
        if (L, num) not in visited:
            DFS(L+1)
            visited.append((L, num)) # ๋‹ค ๊ฐ”๋‹ค๊ฐ€ ์˜ฌ๋ผ์˜ค๋ฉด์„œ ์ฒดํฌ
        price[a], price[b] = price[b], price[a] # ์›์ƒ๋ณต๊ตฌ (๋ฐฑํŠธ๋ž˜ํ‚น)

T = int(input())
for test_case in range(1, T+1):
    price, N = map(int, input().split())
    price = list(map(int, str(price)))
    index = [x for x in range(len(price))]
    visited = []

    mx = -1e9
    DFS(0)
    print('#{} {}'.format(test_case, mx))

 

๐Ÿ”— ์ฐธ๊ณ 

๋ฐฑํŠธ๋ž˜ํ‚น #12 ์ตœ๋Œ€ ์ƒ๊ธˆ (SWEA)