분류: 순열, 백트래킹 /
문제
문제 설명
자연수 N과 M이 주어졌을 때, 아래 조건을 만족하는 길이가 M인 수열을 모두 구하는 프로그램을 작성하시오.
- 1부터 N까지 자연수 중에서 중복 없이 M개를 고른 수열
입력
첫째 줄에 자연수 N과 M이 주어진다. (1 ≤ M ≤ N ≤ 8)
출력
한 줄에 하나씩 문제의 조건을 만족하는 수열을 출력한다. 중복되는 수열을 여러 번 출력하면 안되며, 각 수열은 공백으로 구분해서 출력해야 한다.
수열은 사전 순으로 증가하는 순서로 출력해야 한다.
풀이
- Python
global N,M
def dfs(lst:list[int]):
global N,M
if len(lst) == M:
print(*lst)
return
for x in range(1,N+1):
if x not in lst:
lst.append(x)
dfs(lst)
lst.pop()
def main():
global N,M
N, M = map(int, input().split())
dfs([])
main()
모든 순열 구하기
트리의 깊이는 최대 M.
리프(깊이 M)에 도착하면 순열 원소 하나 완성
`if i not in lst` 조건문으로 lst의 중복 원소 제거.
- itertools
itertools 라이브러리의 조합형 이터레이터 사용
`permutations` 순열
from itertools import permutations
N, M = map(int, input().split())
for p in permutations(range(1, N+1), M):
print(*p)
- permutations 구현
import sys
read = sys.stdin.readline
def permutations(pool: list[int], n: int, r: int):
if r == 0 or r > n:
return [] # [[]]이면 if r == 1 필요없음, len(result)을 위해 []반환
if r == 1:
return [[x] for x in pool]
result = []
for x in pool:
nextPool = [y for y in pool if y != x]
for p in permutations(nextPool, n - 1, r - 1):
result.append([x] + p)
return result
def main():
N, M = map(int, read().split())
pool = list(range(1, N + 1))
for p in permutations(pool, N, M):
print(*p)
main()
`permutations`: 사용하지 않은 `pool`을 받고 pool에서 M개 뽑는 조합
r==0 혹은 pool의 사이즈보다 많이 뽑을 경우 빈 리스트를 반환.
[[]]을 반환하면 r==1일때를 고려하지 않아도 되지만 전체 순열의 수를 의미하는 len(result)가 1이되는게 마음에 안들어서 []을 반환
[[]]가 아닌 []을 반환하면 r==1일 중첩 for문이 실행되지 않음. 따라서 r==1일 때 [[x]]를 반환하는 조건을 추가.
- C++
#include <iostream>
using namespace std;
int N, M;
bool used[9];
int result[8];
void permutation(int size) {
if(size == M) {
for(int i=0; i<size; i++)
cout << result[i] << ' ';
cout << '\n';
return;
}
for(int x=1; x<=N; x++) {
if(used[x]) continue;
result[size] = x;
used[x] = true;
permutation(size + 1);
used[x] = false;
}
}
int main() {
ios::sync_with_stdio(0); cin.tie(0);
cin >> N >> M;
permutation(0);
}
혹은 `result`를 vector로 만들고 `vector.size()`를 이용해도 됨. 대신 재귀 끝나면 `pop_back`
'Problem Solving > BOJ' 카테고리의 다른 글
[백준] N과 M 시리즈 풀이 모음 (0) | 2023.09.09 |
---|---|
[백준 - 15650] N과 M (2) - Python (0) | 2023.09.09 |
[백준 - 9019] DSLR - Python (0) | 2023.09.09 |
[백준 - 7569] 토마토 - C++, Python (0) | 2023.09.08 |
[백준 - 5430] AC - Python (1) | 2023.09.08 |