거북이의 IT 공부
[백준 15649] N과 M(1) - C++ / 백트래킹, 재귀 알고리즘 본문
문제
https://www.acmicpc.net/problem/15649
백트래킹이란?
아래에 정리해 두었다!
순열구현 - 남의 코드로 공부해보기
수열 = 순열(순서가 있음), 조합(뽑기)
일단 백트래킹을 하기 전에 DFS를 구현하는 재귀함수를 공부할 필요가 있다.
"재귀를 통한 순열 구현"에 대해 공부해보자.
* 참고사이트 : https://yabmoons.tistory.com/100
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
#include <iostream>
#include<vector>
#define MAX 5
using namespace std;
int arr[MAX];
bool visited[MAX];
vector<int> vec;
void print() {
for (int i = 0; i < vec.size(); i++)
cout << vec[i] << " ";
cout << '\n';
}
void dfs(int cnt) { //cnt == count약자
if (cnt == 3) {
print();
return;
}
for (int i = 0; i < MAX; i++) {
if (visited[i] == true) continue;
visited[i] = true;
vec.push_back(arr[i]);
dfs(cnt + 1);
vec.pop_back();
visited[i] = false;
}
}
int main(void) {
arr[0] = 1;
arr[1] = 2;
arr[2] = 3;
arr[3] = 4;
arr[4] = 5;
dfs(0);
}
|
cs |
<출력결과>
1 2 3
1 2 4
1 2 5
1 3 2
1 3 4
1 3 5
1 4 2
1 4 3
1 4 5
1 5 2
1 5 3
1 5 4 .....
<이해>
1. cnt=0, i=0
arr = {1}
2. cnt = 1, i=0,1
arr = {1,2}
3. cnt = 2, i=0,1,2
arr = {1,2,3}
4. cnt = 3, 출력
5. "백트래킹"
cnt = 2, i = 2
vec.pop_back(), visited[2] = false
arr = {1, 2}
6. cnt = 2, i = 3
arr = { 1, 2, 4 }
7. cnt = 3, 출력
8. cnt = 2, i = 3
vec.pop_back(), visited[3] = false
arr = {1, 2}
9. cnt = 2, i = 4
arr = {1,2,5}
10. cnt = 3, 출력
-> cnt = 2, i = 4
vec.pop_back(), visited[4] = false
★★★★중요★★★★
11. for문 다 돌아서 cnt = 1, i = 1
vec.pop_back(), visited[1] = false
12. cnt = 1, i = 2
arr = {1, 3}
13. cnt = 2, i = 0, 1
arr = {1,3,2}
14. cnt = 2, i = 1
vec.pop_back(), visited[1] = false
15. cnt = 2, i = 2, 3
arr = {1,3,4}
이런 방식으로 dfs는 재귀로 돌아가고
재귀로 순열을 구할 수 있다.
정답 코드
이제는 순열 구현을 통해 백준 문제를 쉽게 풀 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
#include <iostream>
#include <vector>
# define MAX 8
using namespace std;
int arr[MAX]; //주어진 숫자
bool visited[MAX]; //방문, 중복 방지
vector<int> vec; //출력할 수열
int cnt, n, m;
void Print() {
for (int i = 0; i < vec.size(); i++)
cout << vec[i] << " ";
cout << '\n';
return;
}
void DFS(int cnt) {
if (cnt == m) {
Print();
return;
}
for (int i = 0; i < n; i++) {
if (visited[i]) continue;
visited[i] = true;
vec.push_back(arr[i]);
DFS(cnt + 1);
vec.pop_back();
visited[i] = false;
}
}
int main(void) {
cin >> n >> m;
for (int i = 0; i < n; i++) {
arr[i] = i + 1;
visited[i] = false;
}
DFS(0);
}
|
cs |
'Baekjoon' 카테고리의 다른 글
[백준 15652] N과 M(4) - C++ / 백트래킹, 재귀 알고리즘 (0) | 2020.05.23 |
---|---|
[백준 15650] N과 M(2) - C++ / 백트래킹, 재귀 알고리즘 (0) | 2020.05.15 |
[백준 2583] 영역 구하기 - C++ / 알고리즘 DFS (0) | 2020.05.15 |
[백준 13549] 숨바꼭질 3 - C++ / 알고리즘 BFS, 우선순위 큐 (1) | 2020.04.25 |
[백준 13913] 숨바꼭질 4 - C++ / 알고리즘 BFS (0) | 2020.04.25 |