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

 

15666번: N과 M (12)

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

www.acmicpc.net

 

복기

아래와 같은 N과 M 시리즈 문제

https://smallpants.tistory.com/220

 

이번엔 입력되는 수에 중복이 있다.

예를들어 { 9, 7, 9, 1 }처럼 들어오는데 정렬해서 사용하므로 { 1, 7, 9, 9 }로 생각하고 시작

근데 문제는 1로 시작해서 2개 뽑는다면 11 17 19 19 처럼되는데 19가 두번 나오면 안된다.

 

이전에 비슷한 문제를 풀땐 그냥 중복 제거를 위해 set에다가 값 다 때려넣어버리고 마지막에 set에 있는 수열들을 다 출력해버렸었다.

아래의 정답코드 2번이 해당 방식인데 이렇게 하면 저장공간을 많이 써야하고 같은 수열을 여러번 만드니까 시간도 더 써야한다.

 

구글링해본 결과 좋은 아이디어는 현재 temp에 M - 1개가 들어있을때 

값을 넣으면서 해당 값을 prev 변수에 저장한다.

그리고 나서 M개가 됐으니 해당 수열은 출력

다음 재귀에 다시 M - 1개가 있는데 이때 넣으려는 값이 prev와 같다면 똑같은 수열을 만드는거니까 그냥 넘긴다.

 

즉 매번 있던 수열인지 체크할 필요도 없이 M - 1개 채워진 상황 -> M개 채워지는 상황에서 최근 수열의 마지막값과 현재 마지막으로 넣으려는 값이 같은지만 체크하면 된다.

 

정답코드

1) prev를 사용하는 경우

#include <bits/stdc++.h>
using namespace std;

vector<int> vec, temp;
int N, M;
void recursion(int count, int start)
{	
	if (count == M) {		
		for (auto t : temp) { cout << t << ' '; }
		cout << '\n';
		return;
	}

	int prev = -1;
	for (int i = start; i < N; i++) {
		if (prev != vec[i]) {
			prev = vec[i];
			temp[count] = vec[i];
			recursion(count + 1, i);			
		}
	}
}

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

	cin >> N >> M;
	vec.resize(N);
	temp.resize(M);

	for (int i = 0; i < N; i++) { cin >> vec[i]; }
	sort(vec.begin(), vec.end());

	recursion(0, 0);

	return 0;
}

 

2) set을 사용하는 경우

#include <bits/stdc++.h>
using namespace std;

vector<int> vec, temp;
set<vector<int>> s;
int N, M;
void recursion(int count, int start)
{	
	if (count == M) {		
		s.insert(temp);
		return;
	}

	for (int i = start; i < N; i++) {
		temp[count] = vec[i];
		recursion(count + 1, i);		
	}
}

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

	cin >> N >> M;
	vec.resize(N);
	temp.resize(M);

	for (int i = 0; i < N; i++) { cin >> vec[i]; }
	sort(vec.begin(), vec.end());

	recursion(0, 0);
	for (auto& per : s) {
		for (int i : per) {
			cout << i << ' ';
		}
		cout << '\n';
	}

	return 0;
}