#include <iostream>
#include <iostream>
using namespace std;
int N, M;
int input[10];
int ans[10];
bool isUsed[10];
void func(int L){
if (L == M){
for (int i=0; i<M; i++) cout << ans[i] << ' ';
cout << '\n';
return;
}
int tmp = 0;
for (int i=0; i<N; i++){
if (!isUsed[i] && tmp != input[i]){
ans[L] = input[i];
tmp = input[i];
isUsed[i] = true;
func(L+1);
isUsed[i] = false;
}
}
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
cin >> N >> M;
for (int i=0; i<N; i++) cin >> input[i];
sort(input, input+N);
for (int i=0; i<N; i++) cout << input[i] << ' ';
cout << '\n';
func(0);
return 0;
}
사실 나는 답 코드를 보고 한번에 tmp 변수가 어떻게 저장되고 어떻게 사용되는 지 이해하지 못했다.
그래서 먼저 재귀함수가 Stack 메모리에 어떻게 들어가는지 찾아보았다.
위 그림은 대표적인 재귀함수인 factorial 함수가 stack 메모리에 들어가는 과정이다.
이를 통해 해당 문제의 tmp 변수는 func함수가 불릴 때마다 독립적인 새 변수 주소로 할당되는 것을 알 수 있었다. 즉, tmp변수는 같은 Level에서만 유효하고 다음 Level로 넘어가면 tmp=0으로 초기화된 새로운 변수에서 시작되는 것이다.
따라서 tmp 변수가 input[i] 값을 저장한 이유는 같은 Level에서 중복 수열을 만들지 않기 위해서이다. input 수열을 오름차순으로 정렬했기 때문에 같은 값을 갖는 수가 있다면 바로 옆에 위치할 것이다. tmp값이 이전 수열의 마지막 항을 저장하고 있으므로 같은 Level에서 check하면 중복 수열을 만들지 않게 되는 것이다.