치춘짱베리굿나이스
[백준] 15650 본문
N과 M (2)
문제
자연수 N과 M이 주어졌을 때, 아래 조건을 만족하는 길이가 M인 수열을 모두 구하는 프로그램을 작성하시오.
- 1부터 N까지 자연수 중에서 중복 없이 M개를 고른 수열
- 고른 수열은 오름차순이어야 한다.
입력
첫째 줄에 자연수 N과 M이 주어진다. (1 ≤ M ≤ N ≤ 8)
출력
한 줄에 하나씩 문제의 조건을 만족하는 수열을 출력한다. 중복되는 수열을 여러 번 출력하면 안되며, 각 수열은 공백으로 구분해서 출력해야 한다.
수열은 사전 순으로 증가하는 순서로 출력해야 한다.
풀이
let arr;
let n;
let m;
const recurNandM = (k, l, ans) => {
if (l > n + 1) return;
if (k === m) ans.push(arr.join(" "));
else {
for (let i = l; i <= n; i++) {
arr[k] = i;
recurNandM(k + 1, i + 1, ans);
}
}
};
const nAndM = () => {
[n, m] = require("fs")
.readFileSync("/dev/stdin")
.toString()
.trim()
.split(" ")
.map(Number);
let ans = [];
arr = Array.from({ length: m }, (v) => 0);
recurNandM(0, 1, ans);
console.log(ans.join("\n"));
};
nAndM();
반성회
15649 의 파생문제 답게 거의 비슷한 구성을 보이나, 숫자가 사전순으로 증가한다는 차이점이 있다
따라서 반복문을 돌 때 이전에 사용했던 숫자보다 1 큰 수부터 탐색하며, 어차피 이전에 사용했던 숫자들보다 큰 숫자만을 탐색하므로 숫자가 중복될 일이 전혀 없어 isUsed
배열을 사용하지 않는다
arr
: M자리의 수열을 저장하는 배열, 재귀를 들어갈 때마다 특정 자리수 (k
) 에 숫자를 채워넣는다k
: 수열의 몇 번째 자리를 계산하는지 나타내는 자리수l
: 직전에 수열에 채워넣었던 숫자 (i
) 보다 1 큰 수, 다음 재귀에서 반복문은i = l
부터 시작한다ans
: 나중에 수열을 한꺼번에 출력하기 위해 만든 수열을 저장하는 배열
재귀 진행 순서
k
는 자리수를 나타내고, 0번째 자리부터 채워나가므로recurNandM
의 인자k
는 0으로 설정l
은 재귀함수 내의 반복문에서 반복자i
의 시작점이므로 1로 설정recurNandM
의 탈출조건은 두 종류가 있다l
이n + 1
보다 클 때 :i
의 범위가 1부터n
까지이므로l
의 범위는 1부터n + 1
까지이고, 따라서l
이n + 1
보다 커지면 더이상 수열에 채울 수 있는 숫자가 없으므로 재귀를 탈출한다k
가m
일 때 :k
는 0부터 시작하여m
개 자리를 채우므로k
의 최대값은m - 1
이고, 따라서 k가 m일 땐 원하는 수열의 길이보다 길어지므로 지금까지 만든 수열을ans
에push
하고 재귀를 종료
- 위의 두 경우에 해당되지 않을 경우,
k
번째 자리에 값을 채워넣기 위해 반복문을 돈다- 반복문의 반복자
i
는l
부터n
까지 돈다(직전에 채워넣었던 수보다 1 큰 수부터 채워넣어야 오름차순이 되므로l
부터n
까지의 수가 올 수 있다) - 수열의
k
번째 자리에i
를 채워넣는다 (arr[k] = i
) k
번째 자리에i
를 사용했으므로, 그 뒤에 오는 자리는 무조건i
보다 커야 하므로 다음 재귀의 인자l
에i + 1
을 넣는다- 또한
k
번째 자리를 채워넣었으므로k + 1
번째 자리를 채워넣기 위해 다음 재귀의 인자k
에k + 1
을 넣는다 - 재귀를 빠져나온다는 건
k
번째 자리에i
를 넣는 모든 오름차순 수열을 완성하였거나,l
이n + 1
보다 커 사용할 수 있는 숫자가 없다는 것을 의미하므로, 탐색을 중지한다
- 반복문의 반복자
- 모든 재귀를 빠져나와
recurNandM
을 종료하고nAndM
함수로 돌아왔다는 것은 모든 경우의 수를 탐색하여 가능한 수열을 전부 찾아냈다는 뜻이므로,ans
에 저장된 모든 수열을\n
을 기준으로 구분하여 출력한다
'Javascript + Typescript > 자바스크립트로 알고리즘풀기' 카테고리의 다른 글
[백준] 15654 (0) | 2022.05.05 |
---|---|
[백준] 15651 (0) | 2022.05.05 |
[백준] 1182 (0) | 2022.05.05 |
[백준] 15649 (0) | 2022.05.05 |
[백준] 7785 (0) | 2022.05.05 |
Comments