Notice
250x250
Recent Posts
Recent Comments
Link
넘치게 채우기
[BOJ] N과 M(2) 본문
728x90
반응형
https://www.acmicpc.net/problem/15650
BOJ - N과 M(2)
문제 유형: 백트래킹, dfs, 재귀
문제 난이도: Silver III
시간 제한: 1초
메모리 제한: 512MB
문제
자연수 N과 M이 주어졌을 때, 아래 조건을 만족하는 길이가 M인 수열을 모두 구하는 프로그램을 작성하시오.
- 1부터 N까지 자연수 중에서 중복 없이 M개를 고른 수열
- 고른 수열은 오름차순이어야 한다.
입력
첫째 줄에 자연수 N과 M이 주어진다. (1 ≤ M ≤ N ≤ 8)
출력
한 줄에 하나씩 문제의 조건을 만족하는 수열을 출력한다. 중복되는 수열을 여러 번 출력하면 안되며, 각 수열은 공백으로 구분해서 출력해야 한다.
수열은 사전 순으로 증가하는 순서로 출력해야 한다.
풀이
배열을 (1, 2, ...,n-1 , n)로 만들어서, 이 배열에 대해 중복 없이 백트래킹 해주면 되다.
이 상태로 백트래킹하면서 순차적으로 순열들을 만들면, 순서는 보장되어있다.
solve(idx, seq, arr)을 실행하면,
만약 seq의 크기가 m이라면, 수열을 만들었다는 뜻이므로 출력한다.
그게 아니고 idx가 n 이상이라면, 범위를 벗어났으므로 종료한다.
둘다 아니라면, i = idx ~ n-1까지 한 번씩 백트래킹을 호출한다.
seq의 맨 뒤에 arr[i]를 추가했다가
solve(i+1, seq, arr)을 호출하고 (같은 요소가 중복으로 들어갈 수 없으므로 i+1로 넘어간다)
맨 뒤를 제거해준다.
코드
C++
#include <bits/stdc++.h>
using namespace std;
int n, m;
void solve(int idx, vector<int> &seq, vector<int> &arr) {
if (seq.size() == m) {
for (int i = 0; i < m; ++i) {
cout << seq[i] << " ";
}
cout << "\n";
return;
}
if (idx >= n)
return;
for (int i = idx; i < n; ++i) {
seq.emplace_back(arr[i]);
solve(i + 1, seq, arr);
seq.pop_back();
}
}
int main(int argc, char *argv[]) {
cin >> n >> m;
vector<int> arr(n, 1);
for (int i = 1; i < n; ++i) {
arr[i] += arr[i - 1];
}
vector<int> seq;
solve(0, seq, arr);
return 0;
}
산화 은(II)
728x90
반응형
'PS > BOJ' 카테고리의 다른 글
[BOJ] 11725 - 트리의 부모 찾기 (0) | 2024.10.22 |
---|---|
[BOJ] 11053: 가장 긴 증가하는 부분 수열 (0) | 2024.10.21 |
[BOJ] 15666 - N과 M(12) (0) | 2024.10.19 |
[BOJ] 18405 - 경쟁적 전염 (0) | 2024.10.18 |
[BOJ] 16964 - DFS 스페셜 저지 (0) | 2024.10.17 |