본문 바로가기

Algorithm/DFS

(C++) - 백준(BOJ) 15664번 : N과 M (10)

반응형

문제링크 : https://www.acmicpc.net/problem/15664

 

15664번: N과 M (10)

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

www.acmicpc.net

출력은 무조건 오름차순, 중복 출력하지 않아야 합니다.

 

풀이방법

 1. set으로 중복된 상태를 저장하지 않게 하는 방법

 2. 해당 level의 수를 한 번 뽑았다면 뽑지 못하도록 만드는 2차원 배열을 사용하는 방법

 

Code

1. set으로 푼 코드

#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
using namespace std;
int n, m;
int a[8];
int ck[8];
int tmp[8];
set<vector<int>> ans;
//중복 저장을 하지 않는 set이용
void DFS(int level,int node)
{
    if (level == m)
    {
        vector<int> v;
        for (int i = 0; i < m; i++)
            v.push_back(tmp[i]);
        //set에 무조건 때려박는다
        ans.insert(v);
        v.clear();
        return;
    }
    for (int i = node; i < n; i++)
    {    
        
            tmp[level] = a[i];
            DFS(level + 1,i+1);
        
    }
}
int main() {
    cin >> n >> m;
    for (int i = 0; i < n; i++)
    {
        cin >> a[i];
    }
    sort(a, a + n);//정렬
    DFS(0,0);

    for (auto a : ans)
    {
        for (int i = 0; i < a.size(); i++)
        {
            cout << a[i] << ' ';
        }
        cout << '\n';
    }
}

 

2. set으로 풀지 않았을 때 :

다음 노드로 넘어갈 때까지 뽑았던 해당 깊이(level)의 숫자를 뽑지 않습니다.

#include <bits/stdc++.h>
using namespace std;
int n,m;
vector<int> num, v;
int ck2[10001][10];
int ck[10001];
void backtracking(int depth){
    if(depth == m){
        for(int i = 0; i < m; i++){
            cout << v[i] << ' ';
        }
        cout << '\n';
        return;
    }

    for(int i = 0; i < n; i++){
        if(ck[i] || ck2[num[i]][depth]) continue;
        ck[i] = 1;
        ck2[num[i]][depth] = 1;
        v.push_back(num[i]);
        backtracking(depth + 1);
        v.pop_back();
        ck[i] = 0;
    }

    for(int i = 0; i < n; i++){
        ck2[num[i]][depth] = 0;
    }
}

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