# 생각

조합의 개수를 구하는 문제이다

다중 for문을 사용하지 않고 backtracking 방법을 사용하면 된다

 

각 숫자는 수열에서 딱 한번씩만 사용되므로

bfs / dfs에서의 풀이를 활용하여 각 수에 대한 bool형 배열 bUsed를 선언,

해당 수를 사용 유무를 저장한다

 

1부터 n까지 수에 대해 사용되지 않은 수가 있다면 그 수를 넣고

사용했다고 true로 명시한 후에 다음 수를 정하는 함수를 재귀방식으로 작성한다

수를 정한 모든 경우에 대해 다 확인한 후 다시 false로 되돌아가주면

원하는 수열을 뽑아낼 수 있다

 

 

# 전체 코드

#include <bits/stdc++.h>
using namespace std;
// R : 1s, 512MB
// 1 <= M <= N <= 8
int arr[10];
bool bUsed[10];

void funcRecursive(int k, int n, int m)	// 현재 k개까지 수를 선택
{
	if (k == m)	// m개를 모두 선택했다면
	{
		for (int i = 0; i < m; i++)
		{
			cout << arr[i] << ' ';
		}
		cout << '\n';
		return;
	}

	for (int i = 1; i <= n; i++)	// 1부터 n까지의 수에대해
	{
		if (bUsed[i] == false)	// 아직 i가 사용되지 않았다면
		{
			arr[k] = i;	// k번째 수를 i로 정한다
			bUsed[i] = true;	// i는 사용했다고 명시
			funcRecursive(k + 1, n, m);	// 다음 수를 정하러 한 단계 더 들어간다
			bUsed[i] = false;	// k번째 수를 i로 정한 모든 경우에 대해 다 확인하면 i를 다시 미사용으로 
		}
	}
}

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	int N, M;
	cin >> N >> M;
	funcRecursive(0, N, M);
}

 

 

# next_permutation을 이용한 코드

// R : 1s, 512MB
// 1 <= M <= N <= 8
#include <bits/stdc++.h>
using namespace std;

void dfs2(int n, int m)
{
	vector<int> v;
	for (int i = 1; i <= n; i++)
	{
		v.push_back(i);
	}
	do
	{
		reverse(v.begin() + m, v.end());
		for (int i = 0; i < m; i++)
		{
			cout << v[i] << ' ';
		}
		cout << '\n';
	} while (next_permutation(v.begin(), v.end()));
}

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	int N, M;
	cin >> N >> M;
	dfs2(N, M);
}

https://www.acmicpc.net/problem/15649

 

15649번: N과 M (1)

한 줄에 하나씩 문제의 조건을 만족하는 수열을 출력한다. 중복되는 수열을 여러 번 출력하면 안되며, 각 수열은 공백으로 구분해서 출력해야 한다. 수열은 사전 순으로 증가하는 순서로 출력해

www.acmicpc.net

'Algorithm > BOJ' 카테고리의 다른 글

[BOJ] 1182_부분수열의 합 with cpp  (0) 2022.02.03
[BOJ] 9663_N-Queen with cpp  (0) 2022.02.01
[BOJ] 14956_Philosopher's walk with cpp  (0) 2022.01.31
[BOJ] 2448_별 찍기 - 11 with cpp  (0) 2022.01.30
[BOJ] 2447_별 찍기 - 10 with cpp  (0) 2022.01.29

+ Recent posts