https://www.acmicpc.net/problem/15663
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
vector<int> arr;
vector<int> ans;
bool visit[10];
int n, m;
void dfs(int cnt) {
if (cnt == m) {
for (int i=0;i<m;i++) {
cout << ans[i] << " ";
}
cout << "\n";
return;
}
int temp = 0;
for (int i = 0; i < n; i++) {
if (!visit[i] && temp != arr[i]) {
ans[cnt] = arr[i];
temp = ans[cnt];
visit[i] = true;
dfs(cnt + 1);
visit[i] = false;
}
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
cin >> n >> m;
arr.resize(n);
ans.resize(n);
for (int i = 0; i < n; i++) {
cin >> arr[i];
}
sort(arr.begin(), arr.end());
dfs(0);
return 0;
}
백트래킹 문제이다.
다른 n과 m 문제와 달리 같은 수열을 처리하는 것이 관건이다.
풀이
for (int i = 0; i < n; i++) {
cin >> arr[i];
}
sort(arr.begin(), arr.end());
배열을 입력받고, 정답이 사전 증가 순으로 출력되어야 하므로 정렬한다.
void dfs(int cnt) {
if (cnt == m) {
for (int i=0;i<m;i++) {
cout << ans[i] << " ";
}
cout << "\n";
return;
}
int temp = 0;
for (int i = 0; i < n; i++) {
if (!visit[i] && temp != arr[i]) {
ans[cnt] = arr[i];
temp = ans[cnt];
visit[i] = true;
dfs(cnt + 1);
visit[i] = false;
}
}
}
이 문제는 중복된 수열을 허용하지 않는 것이 관건이다. 다음 입력이 주어졌다고 하자.
1 2 3 4 4
현재 수열이 3 2 라고 가정할 때 다음에 들어갈 수 있는 숫자는 1, 4, 4이다. 여기서 4는 중복되므로 한 번만 출력한다. 즉, 같은 깊이에서의 중복만 체크한다면 중복된 수열을 처리할 수 있다. 이런 식으로 숫자를 조합하여 주어진 길이인 m에 도달했을 경우 그 배열을 출력하면 정답을 구할 수 있다.
'Coding Test' 카테고리의 다른 글
| 백준 3079 입국심사 (1) | 2024.05.28 |
|---|---|
| 백준 1654 랜선 자르기 (0) | 2024.05.27 |
| 백준 10427 빚 (1) | 2024.05.25 |
| 백준 2473 세 용액 (0) | 2024.05.24 |
| 백준 16926 배열 돌리기 1 (0) | 2024.05.23 |