Chomu's Blog.

>

Posts

GitHub

백준 N과 M 시리즈 itertools로 정복하기

목차

개요

Python의 내장 모듈 itertools는 다양한 반복자를 제공한다.
이를 이용하면 반복문을 사용하지 않고도 풀 수 있는 문제들이 많다.
특히 'N과 M' 시리즈의 문제는 수열을 다양한 방식으로 출력해야 하는 문제로 itertools를 사용하면 매우 간단하게 풀 수 있다.
이번 글에서는 백준 'N과 M' 시리즈의 문제를 Python 내장 모듈인 itertools로 풀어보자.

itertools

본격적으로 문제를 풀기 전에 간략하게 itertools에 대해 알아보자.

문제 풀이

본격적으로 문제를 풀어보자.

N과 M(1)

1부터 N까지 자연수 중에서 중복 없이 M개를 고른 수열을 사전순으로 출력해야한다. 중복 없는 수열이므로 순열 즉, itertools.permutations를 사용한다.

from itertools import permutations
N, M = map(int, input().split())
nums = [str(i) for i in range(1, N + 1)]
# join을 사용하기 위해 미리 문자열로 변환
combs = permutations(nums, M)
print('\n'.join(' '.join(comb) for comb in combs))

풀이

N과 M(2)

1부터 N까지 자연수 중에서 중복 없이 M개를 고른 오름차순의 수열을 사전순으로 출력해야한다. 중복 없는 오름차순 수열이므로 조합 즉, itertools.combinations를 사용한다.

from itertools import combinations
N, M = map(int, input().split())
nums = [str(i) for i in range(1, N + 1)]
combs = combinations(nums, M)
print('\n'.join(' '.join(comb) for comb in combs))

풀이

N과 M(3)

1부터 N까지 자연수 중에서 M개를 고른 수열을 사전순으로 출력해야한다. 중복이 허용되므로 itertools.product를 사용한다.

from itertools import product
N, M = map(int, input().split())
nums = [str(i) for i in range(1, N + 1)]
combs = product(nums, repeat=M)
print('\n'.join(' '.join(comb) for comb in combs))

풀이

N과 M(4)

1부터 N까지 자연수 중에서 M개를 고른 비내림차순 수열을 사전순으로 출력해야한다. 비내림차순 수열이므로 중복을 허용하는 조합 즉, itertools.combinations_with_replacement를 사용한다.

from itertools import combinations_with_replacement
N, M = map(int, input().split())
nums = [str(i) for i in range(1, N + 1)]
combs = combinations_with_replacement(nums, M)
print('\n'.join(' '.join(comb) for comb in combs))

풀이

N과 M(5)

주어진 중복되지 않는 N개의 수 중에서 중복 없이 M개를 고른 수열을 사전순으로 출력해야한다. 1번과 비슷하지만 주어진 수열이 있으므로 이를 정렬해야 한다.

from itertools import permutations
N, M = map(int, input().split())
nums = sorted(input().split(), key=int)
# key를 int로 주지 않으면 문자열로 정렬되므로 주의
# sorted(["10", "2"]) -> ["10", "2"]
# sorted(["10", "2"], key=int) -> ["2", "10"]
combs = permutations(nums, M)
print('\n'.join(' '.join(comb) for comb in combs))

풀이

N과 M(6)

주어진 중복되지 않는 N개의 수 중에서 중복 없이 M개를 고른 오름차순 수열을 사전순으로 출력해야한다. 2번과 비슷하지만 주어진 수열이 있으므로 이를 정렬해야 한다.

from itertools import combinations
N, M = map(int, input().split())
nums = sorted(input().split(), key=int)
combs = combinations(nums, M)
print('\n'.join(' '.join(comb) for comb in combs))

풀이

N과 M(7)

주어진 중복되지 않는 N개의 수 중에서 M개를 고른 오름차순 수열을 사전순으로 출력해야한다. 3번과 비슷하지만 주어진 수열이 있으므로 이를 정렬해야 한다.

from itertools import product
N, M = map(int, input().split())
nums = sorted(input().split(), key=int)
combs = product(nums, repeat=M)
print('\n'.join(' '.join(comb) for comb in combs))

풀이

N과 M(8)

주어진 중복되지 않는 N개의 수 중에서 M개를 고른 비내림차순 수열을 사전순으로 출력해야한다. 4번과 비슷하지만 주어진 수열이 있으므로 이를 정렬해야 한다.

from itertools import combinations_with_replacement
N, M = map(int, input().split())
nums = sorted(input().split(), key=int)
combs = combinations_with_replacement(nums, M)
print('\n'.join(' '.join(comb) for comb in combs))

풀이

N과 M(9)

주어진 N개의 수 중에서 중복 없이 M개를 고른 수열을 사전순으로 출력해야한다. 5번과 비슷하지만 중복된 수가 주어질 수 있으므로 수열을 정렬해야 한다.

from itertools import permutations
N, M = map(int, input().split())
nums = map(int, input().split())
combs = sorted(set(permutations(nums, M)))
print('\n'.join(' '.join(map(str, comb)) for comb in combs))

풀이

N과 M(10)

주어진 N개의 수 중에서 중복 없이 M개를 고른 비내림차순 수열을 사전순으로 출력해야한다. 8번과 비슷하지만 중복된 수가 주어질 수 있으므로 주어진 수와 수열을 정렬해야 한다.

from itertools import combinations
N, M = map(int, input().split())
nums = sorted(map(int, input().split()))
combs = sorted(set(combinations(nums, M)))
print('\n'.join(' '.join(map(str, comb)) for comb in combs))

풀이

N과 M(11)

주어진 N개의 수 중에서 중복 없이 M개를 고른 수열을 사전순으로 출력해야한다. 7번과 비슷하지만 중복된 수가 주어질 수 있으므로 주어진 수를 정렬해야 한다.

from itertools import product
N, M = map(int, input().split())
nums = sorted(set(map(int, input().split())), key=int)
combs = product(nums, repeat=M)
print('\n'.join(' '.join(map(str, comb)) for comb in combs))

풀이

N과 M(12)

주어진 N개의 수 중에서 M개를 고른 비내림차순 수열을 사전순으로 출력해야한다. 9번과 비슷하지만 중복된 수가 주어질 수 있으므로 주어진 수와 수열을 정렬해야 한다.

from itertools import combinations_with_replacement
N, M = map(int, input().split())
nums = sorted(set(map(int, input().split())), key=int)
combs = sorted(set(combinations_with_replacement(nums, M)))
print('\n'.join(' '.join(map(str, comb)) for comb in combs))

풀이

여담

비슷한 이름의 N과 M이라는 문제가 있다. 하지만 전혀 다른 문제이므로 여기에 풀이를 적진 않을 것이다.