알고리즘 문제풀이

[백준 15664] N과 M (9) (C++)

SiO2whocode 2024. 6. 22. 23:28
728x90

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

 

백트래킹

N과 M (5)와 비슷하게 N개의 자연수 중에 M개를 뽑아 만들 수 있는 수열을 모두 사전순으로 출력하는 문제인데

차이점은 N개의 자연수가 중복가능임

그래도 N개의 숫자 중에 M개를 뽑아야 하는 것을 변함이 없어서

그냥 중복된 숫자가 있는 숫자 카드가 N개 있고, 그 중 M개를 뽑아서 나열한 수열을 중복되지 않게, 사전순으로 출력하믄댐!

 

접근방법

N과 M(5) 코드에서 수열을 담고 있는 배열을 vector가 아닌 set으로 바꿔주면 됨~

set<vector<int>, less<vector<int>>> 이렇게 선언하면 사전순으로 수열이 정렬되어서 set에 들어감

 

오답노트

set에서 vector 정렬 안될 줄 알고 string으로 넣었다가 9, 10 이런 경우 문자열대로 사전순 정렬하면 10, 9 이렇게 나와서 틀림

set에서 벡터 그냥 정렬되니까 그냥 쓰면 될듯

 

소스코드

#include <iostream>
#include <vector>
#include <set>
#include <algorithm>
using namespace std;

vector<int> num;
set<vector<int>, less<vector<int>>> result;

void recursive(int n, int m, vector<int> arr, vector<bool> visit){
    int size = arr.size();
    if(size == m){
        result.insert(arr);
    } else {
        for(int i = 0; i < num.size(); i++){
            if(!visit[i]){
                vector<int> _arr = arr;
                _arr.push_back(num[i]);
                vector<bool> _visit = visit;
                _visit[i] = true;
                recursive(n, m, _arr, _visit);
            }
        }
    }
}

int main(){
    
    int N, M;
    cin >> N >> M;
        
    for(int i = 0; i < N; i++){
        int n;
        cin >> n;
        num.push_back(n);
    }
    
    sort(num.begin(), num.end());

    vector<int> arr;
    vector<bool> visit(N,false);
    recursive(N, M, arr, visit);

    for(const auto& s: result) {
        for(int n: s)
            cout << n << " ";
        cout << "\n";
    }
    
    return 0;
}
728x90