반응형
문제링크 : https://www.acmicpc.net/problem/15664
출력은 무조건 오름차순, 중복 출력하지 않아야 합니다.
풀이방법
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);
}
'Algorithm > DFS' 카테고리의 다른 글
(C++) - 백준(BOJ) 1182번 : 부분수열의 합 (0) | 2020.01.15 |
---|---|
(C++) - DFS 유형 (0) | 2020.01.15 |
(C++) - 백준(BOJ) 15663번 : N과 M (9) (0) | 2019.09.28 |
(C++) - 백준(BOJ) 15649번 : N과 M (1) (0) | 2019.09.24 |
(C++) - 백준(BOJ) 2252번 : 줄 세우기 (0) | 2017.02.14 |