[AlgoSpot][Python] ์†Œํ’

๊น€์ง€ํ›ˆยท2023๋…„ 12์›” 15์ผ

์•Œ๊ณ ๋ฆฌ์ฆ˜

๋ชฉ๋ก ๋ณด๊ธฐ
2/19

๐Ÿ“’ ๋ฌธ์ œ ์„ค๋ช…

๐Ÿ”– https://www.algospot.com/judge/problem/read/PICNIC

๐Ÿ“– ๋ฌธ์ œ
์•ˆ๋“œ๋กœ๋ฉ”๋‹ค ์œ ์น˜์› ์ต์Šคํ”„๋ ˆ์Šค๋ฐ˜์—์„œ๋Š” ๋‹ค์Œ ์ฃผ์— ์œจ๋™๊ณต์›์œผ๋กœ ์†Œํ’์„ ๊ฐ‘๋‹ˆ๋‹ค. ์›์„ ์„ ์ƒ๋‹˜์€ ์†Œํ’ ๋•Œ ํ•™์ƒ๋“ค์„ ๋‘ ๋ช…์”ฉ ์ง์„ ์ง€์–ด ํ–‰๋™ํ•˜๊ฒŒ ํ•˜๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์„œ๋กœ ์นœ๊ตฌ๊ฐ€ ์•„๋‹Œ ํ•™์ƒ๋“ค๋ผ๋ฆฌ ์ง์„ ์ง€์–ด ์ฃผ๋ฉด ์„œ๋กœ ์‹ธ์šฐ๊ฑฐ๋‚˜ ๊ฐ™์ด ๋Œ์•„๋‹ค๋‹ˆ์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์—, ํ•ญ์ƒ ์„œ๋กœ ์นœ๊ตฌ์ธ ํ•™์ƒ๋“ค๋ผ๋ฆฌ๋งŒ ์ง์„ ์ง€์–ด ์ค˜์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๊ฐ ํ•™์ƒ๋“ค์˜ ์Œ์— ๋Œ€ํ•ด ์ด๋“ค์ด ์„œ๋กœ ์นœ๊ตฌ์ธ์ง€ ์—ฌ๋ถ€๊ฐ€ ์ฃผ์–ด์งˆ ๋•Œ, ํ•™์ƒ๋“ค์„ ์ง์ง€์–ด์ค„ ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์˜ ์ˆ˜๋ฅผ ๊ณ„์‚ฐํ•˜๋Š” ํ”„๋กœ๊ทธ๋žจ์„ ์ž‘์„ฑํ•˜์„ธ์š”. ์ง์ด ๋˜๋Š” ํ•™์ƒ๋“ค์ด ์ผ๋ถ€๋งŒ ๋‹ค๋ฅด๋”๋ผ๋„ ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์ด๋ผ๊ณ  ๋ด…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๋‹ค์Œ ๋‘ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์€ ์„œ๋กœ ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค.

  • (ํƒœ์—ฐ,์ œ์‹œ์นด) (์จ๋‹ˆ,ํ‹ฐํŒŒ๋‹ˆ) (ํšจ์—ฐ,์œ ๋ฆฌ)
  • (ํƒœ์—ฐ,์ œ์‹œ์นด) (์จ๋‹ˆ,์œ ๋ฆฌ) (ํšจ์—ฐ,ํ‹ฐํŒŒ๋‹ˆ)

โœ ์ž…๋ ฅ
์ž…๋ ฅ์˜ ์ฒซ ์ค„์—๋Š” ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค์˜ ์ˆ˜ C (C <= 50) ๊ฐ€ ์ฃผ์–ด์ง‘๋‹ˆ๋‹ค. ๊ฐ ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค์˜ ์ฒซ ์ค„์—๋Š” ํ•™์ƒ์˜ ์ˆ˜ n (2 <= n <= 10) ๊ณผ ์นœ๊ตฌ ์Œ์˜ ์ˆ˜ m (0 <= m <= n*(n-1)/2) ์ด ์ฃผ์–ด์ง‘๋‹ˆ๋‹ค. ๊ทธ ๋‹ค์Œ ์ค„์— m ๊ฐœ์˜ ์ •์ˆ˜ ์Œ์œผ๋กœ ์„œ๋กœ ์นœ๊ตฌ์ธ ๋‘ ํ•™์ƒ์˜ ๋ฒˆํ˜ธ๊ฐ€ ์ฃผ์–ด์ง‘๋‹ˆ๋‹ค. ๋ฒˆํ˜ธ๋Š” ๋ชจ๋‘ 0 ๋ถ€ํ„ฐ n-1 ์‚ฌ์ด์˜ ์ •์ˆ˜์ด๊ณ , ๊ฐ™์€ ์Œ์€ ์ž…๋ ฅ์— ๋‘ ๋ฒˆ ์ฃผ์–ด์ง€์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํ•™์ƒ๋“ค์˜ ์ˆ˜๋Š” ์ง์ˆ˜์ž…๋‹ˆ๋‹ค.

๐Ÿ’ป ์ถœ๋ ฅ
๊ฐ ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค๋งˆ๋‹ค ํ•œ ์ค„์— ๋ชจ๋“  ํ•™์ƒ์„ ์นœ๊ตฌ๋ผ๋ฆฌ๋งŒ ์ง์ง€์–ด์ค„ ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์˜ ์ˆ˜๋ฅผ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค.


โœ๏ธ ํ’€์ด ๊ณผ์ •

๐Ÿ“ 1์ฐจ ์‹œ๋„

  • ๊ฐ€๋Šฅํ•œ n์˜ ์ตœ๋Œ“๊ฐ’์ด 10์œผ๋กœ ํฌ์ง€ ์•Š๊ณ , ๊ฐ€๋Šฅํ•œ ๋ชจ๋“  ์กฐํ•ฉ์˜ ๊ฐœ์ˆ˜๋ฅผ ๊ตฌํ•˜๋Š” ๋ฌธ์ œ์ด๋ฏ€๋กœ ์™„์ „ ํƒ์ƒ‰์œผ๋กœ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค.

  • ์›์†Œ์˜ ์ˆœ์„œ๋งŒ ๋‹ค๋ฅธ ์ˆœ์„œ์Œ์ด๋‚˜ ์กฐํ•ฉ์„ ์ค‘๋ณตํ•ด์„œ ์นด์šดํŠธํ•˜์ง€ ์•Š๋„๋ก ์ฃผ์˜ํ•ด์•ผ ํ•œ๋‹ค. (์šฐ์„  ์ˆœ์œ„ ํ•„์š”)

  • ์šฐ์„  ๊ต์žฌ์—์„œ ์†Œ๊ฐœํ•œ ๋Œ€๋กœ first_free ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ง์ด ์ง€์–ด์ง€์ง€ ์•Š์€ ํ•™์ƒ ์ค‘์—์„œ ๋ฒˆํ˜ธ๊ฐ€ ๊ฐ€์žฅ ์ž‘์€ ํ•™์ƒ์— ๋Œ€ํ•˜์—ฌ ๋จผ์ € ์ง์„ ์ฐพ๋„๋ก ํ–ˆ๋‹ค.

  • first_free๊ฐ€ -1์ธ ๊ฒฝ์šฐ, ์ง์ด ์ง€์–ด์ง€์ง€ ์•Š์€ ํ•™์ƒ์ด ์—†๋Š” ๊ฒƒ์ด๋ฏ€๋กœ 1์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

โœจ ์†Œ์Šค ์ฝ”๋“œ

import sys
input = sys.stdin.readline

def countingPairs(taken, are_friends):
	ans = 0
    first_free = taken.index(False) if False in taken else -1
    if first_free == -1: return 1

    for pair_with in range(first_free + 1, students_count):
        if (not taken[first_free] and not taken[pair_with] and are_friends[first_free][pair_with]):
            taken[first_free] = taken[pair_with] = True
            ans += countingPairs(taken, are_friends)
            # ๋ฐฑํŠธ๋ž˜ํ‚น
            taken[first_free] = taken[pair_with] = False
    return ans

C = int(input())

for _ in range(C):
    students_count, friends_count = map(int, input().split())
    taken = [False] * students_count
    friends_list = list(map(int, input().split()))
    are_friends = [[False] * students_count for _ in range(students_count)]

    for i in range(0, friends_count * 2, 2):
        are_friends[friends_list[i]][friends_list[i + 1]] = True
        are_friends[friends_list[i + 1]][friends_list[i]] = True

    print(countingPairs(taken, are_friends))

๐Ÿ“ 2์ฐจ ์‹œ๋„

  • 2์ฐจ์› ๋ฐฐ์—ด are_freinds๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  friends_list ๋ฐฐ์—ด์„ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉํ•˜์˜€์œผ๋ฉฐ, countingPairs ํ•จ์ˆ˜์˜ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ start๋ฅผ ์‚ฌ์šฉํ–ˆ๋‹ค.

  • start ๊ฐ’์ด ์ฆ๊ฐ€ํ•จ์— ๋”ฐ๋ผ ๋ฐฑํŠธ๋ž˜ํ‚น์„ ์‹œํ–‰ํ•˜๋ฏ€๋กœ ์ค‘๋ณต๋œ ์ˆœ์„œ์Œ์ด ์นด์šดํŠธ๋˜์ง€ ์•Š๋Š”๋‹ค.

  • ๋”ฐ๋ผ์„œ first_free ๋ณ€์ˆ˜๊ฐ€ ์‚ญ์ œ๋˜์—ˆ๊ณ , taken์ด ๋ชจ๋‘ ์ฐธ์ผ ๋•Œ 1์„ ๋ฐ˜ํ™˜ํ•˜๋„๋ก ํ–ˆ๋‹ค.

โœจ ์†Œ์Šค ์ฝ”๋“œ

import sys
input = sys.stdin.readline

def countingPairs(taken, start):
    ans = 0
    if all(t for t in taken): return 1

    for i in range(start, friends_count):
        idx1, idx2 = friends_list[i * 2], friends_list[i * 2 + 1]
        if not taken[idx1] and not taken[idx2]:
            taken[idx1] = taken[idx2] = True
            ans += countingPairs(taken, i + 1)
            taken[idx1] = taken[idx2] = False
    return ans

C = int(input())

for _ in range(C):
    students_count, friends_count = map(int, input().split())
    taken = [False] * students_count
    friends_list = list(map(int, input().split()))

    print(countingPairs(taken, 0))

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