넘치게 채우기

[BOJ] 15666 - N과 M(12) 본문

PS/BOJ

[BOJ] 15666 - N과 M(12)

riveroverflow 2024. 10. 19. 13:44
728x90
반응형

https://www.acmicpc.net/problem/15666

BOJ - N과 M(12)

문제 유형: DFS, 재귀, 백트래킹

문제 난이도: Silver II

시간 제한: 2초

메모리 제한: 512MB

 

문제

N개의 자연수와 자연수 M이 주어졌을 때, 아래 조건을 만족하는 길이가 M인 수열을 모두 구하는 프로그램을 작성하시오.

  • N개의 자연수 중에서 M개를 고른 수열
  • 같은 수를 여러 번 골라도 된다.
  • 고른 수열은 비내림차순이어야 한다.
    • 길이가 K인 수열 A가 A1 ≤ A2 ≤ ... ≤ AK-1 ≤ AK를 만족하면, 비내림차순이라고 한다.

 

입력

첫째 줄에 N과 M이 주어진다. (1 ≤ M ≤ N ≤ 8)

둘째 줄에 N개의 수가 주어진다. 입력으로 주어지는 수는 10,000보다 작거나 같은 자연수이다.

 

출력

한 줄에 하나씩 문제의 조건을 만족하는 수열을 출력한다. 중복되는 수열을 여러 번 출력하면 안되며, 각 수열은 공백으로 구분해서 출력해야 한다.

수열은 사전 순으로 증가하는 순서로 출력해야 한다.

 

풀이

n개의 수를 입력받아서, 정렬 후 중복을 제거한다.

arr.erase(unique(arr.begin(), arr.end()), arr.end());을 이용해서 중복을 제거하려는 경우, 정렬되어있어야 한다.

set에 받았다가 배열에 담는 것도 괜찮다.

그 뒤, n을 새로 할당한다.

 

그 뒤, solve(idx, seq, arr)을 solve(0, seq, arr)로 호출한다. seq는 빈 배열로 시작한다.

solve의 로직은 다음과 같다:

  우선, seq의 크기가 m이 되었다면, 수열을 하나 만들었다는 뜻이므로 출력해주고 리턴한다.

  그게 아니고 인덱스가 범위를 넘었다면, 그냥 리턴한다. 사실 인덱스가 범위를 넘지 않도록 보장되어있으나, 혹시 모르니 넣는다.

 

  i를 idx부터 n이전까지 반복한다.

    arr[i]를 seq 맨 뒤에 삽입하고, 재귀 호출로 solve(i, seq, arr)을 한다.

    그 뒤, seq의 맨 뒤를 제거한다.

 

 

코드

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, seq, arr);
    seq.pop_back();
  }
}

int main(int argc, char *argv[]) {

  cin >> n >> m;
  vector<int> arr(n);
  for (int i = 0; i < n; ++i) {
    cin >> arr[i];
  }
  sort(arr.begin(), arr.end());
  arr.erase(unique(arr.begin(), arr.end()), arr.end());
  n = arr.size();

  vector<int> seq;
  solve(0, seq, arr);

  return 0;
}
 
728x90
반응형

'PS > BOJ' 카테고리의 다른 글

[BOJ] 11053: 가장 긴 증가하는 부분 수열  (0) 2024.10.21
[BOJ] N과 M(2)  (0) 2024.10.20
[BOJ] 18405 - 경쟁적 전염  (0) 2024.10.18
[BOJ] 16964 - DFS 스페셜 저지  (0) 2024.10.17
[BOJ] 14501 - 퇴사  (0) 2024.10.16