본문 바로가기

CodingTest Exam/[C++] Algorithm Study

82. 순열구하기(DFS : Depth First Search) (it 취업을 위한 알고리즘 문제풀이 입문 (with C/C++) : 코딩테스트 대비) ★★★★☆

#include <stdio.h>

int n, r, cnt = 0;
int a[17];
int ch[17];
int res[17];

using namespace std;

void DFS(int x)
{
	if(x == r)
	{
		for(int i = 0; i < r; i++)
			printf("%d ", res[i]);
		printf("\n");
		cnt++;
	}
	else
	{
		for(int i = 1; i <= n; i++)
		{
			if(ch[i] == 0)
			{
				ch[i] = 1;
				res[x] = a[i];
				DFS(x+1);
				ch[i] = 0;
			}
		}
	}
}

int main()
{
	scanf("%d %d", &n, &r);
	
	for(int i = 1; i <= n; i++)
		scanf("%d", &a[i]);
		
	DFS(0); // 2번 설명
	
	printf("%d", cnt);
	
	return 0;
}

1. 입력할 숫자의 개수 n, 뽑을 숫자의 개수 r, 입력된 숫자를 저장할 배열 a, 그 숫자가 쓰였는지 확인할 배열 ch, r개의 숫자를 저장했다가 출력하기 위한 배열 res전역변수로 선언한다. 배열의 원소를 0으로 초기화하고 DFS() 재귀함수에서 사용하기 위함이다.

 

n = 4

r = 3

a = [ 1, 3, 6, 7 ]

ch = [ 0, 0, 0, 0 ]

res = [ 0, 0, 0, 0]

 

2. DFS(int x) 에서 x는 깊이를 의미한다. 트리의 깊이가 r이 된다면 r개의 숫자를 뽑았다고 판단할 수 있다. 따라서 시작은 숫자를 뽑지 않았으므로 0으로 시작한다.

 

3. x 가 0에서 증가할 때

  • 첫 번째 숫자가 쓰였는지 확인한다.( i = 1 ) ch[i] = 0 이기 때문에 쓰인 적이 없으므로 ch[i] = 1로 해주고 배열 a의 첫 번째 원소인 a[1]res의 x 번째에 넣어준다. 여기서 res의 x 번째에 넣는 이유는 x 레벨(깊이)의 노드의 번호이기 때문이다. res에 값을 할당하고나면 다음 깊이를 탐색하기위해 DFS(x+1)을 한다.

4. x 가 r 이 될 때

  • 깊이가 r이 되었다는 것은 r개만큼 숫자를 뽑았다는 의미이다. 문제에서 지나간 노드 번호를 출력하라고 했으므로 배열 res를 순회하면서 원소를 출력하고 줄바꿈을 해준다. 이 때 경우의 수 1개를 찾았으므로 cnt++을 한다.

printf로 출력 후 cnt ++

 

printf로 출력 후 cnt ++

 

printf로 출력 후 cnt ++