15666번: N과 M (12)
한 줄에 하나씩 문제의 조건을 만족하는 수열을 출력한다. 중복되는 수열을 여러 번 출력하면 안되며, 각 수열은 공백으로 구분해서 출력해야 한다. 수열은 사전 순으로 증가하는 순서로 출력해
www.acmicpc.net
- N과 M 시리즈 (9) 번 문제와 아주 유사한 문제로, 중복 허용이 추가되었다.
- 9번에서는 수열을 모두 저장한 후에 수열을 뽑았을 때 기존 수열들과 전부 비교하는 방식으로 풀었었는데, 이번 문제는 좀 더 효율적인 로직을 선택했다.
- 입력 값들이 모두 정렬되어 있는 상태이기 때문에 임의의 자릿수를 뽑을 때 직전에 뽑았던 데이터와 중복되면 넘어가고, 아닐 경우 직전 값을 갱신해주면 중복된 수열을 막을 수 있다.
- 값은 중복되어도 되기 때문에 같은 자릿수에서만 같은 값이 나오지 않게 처리해주면 된다.
#include <iostream>
#include <algorithm>
using namespace std;
int n, m;
int data[8];
int ans[8];
void check(int cur, int size)
{
if(size == m)
{
for(int i = 0 ; i < m ; i++) // m 개를 다 뽑았을 시 뽑은 값들 출력 후 종료
{
cout << ans[i] << " ";
}
cout << '\n';
return;
}
int bef = 0; // 같은 자릿수의 값들 중에서는 같은 값이 나오지 않게
for(int i = cur ; i < n ; i++) // 중복이 허용되므로 시작은 현재 값부터
{
if(data[i] != bef) // 값들이 정렬되어있으므로, 직전에 뽑았던 값이 아닐 경우에만 실행
{
bef = data[i];
ans[size] = data[i]; // 이번 자릿수 결정해주고
check(i, size + 1); // 다음 자릿수 뽑음
}
}
}
int main(void)
{
cin >> n >> m;
for(int i = 0 ; i < n ; i++)
{
cin >> data[i];
}
sort(data, data+n);
check(0, 0); // 0 부터 시작
}
'PS > BOJ' 카테고리의 다른 글
[백준] 11660.cpp : 구간 합 구하기 5 (0) | 2020.08.07 |
---|---|
[백준] 5639.cpp : 이진 검색 트리 (0) | 2020.08.06 |
[백준] 1991.cpp : 트리 순회 (0) | 2020.08.04 |
[백준] 1932.cpp : 정수 삼각형 (0) | 2020.08.03 |
[백준] 1629.cpp : 곱셈 (0) | 2020.07.31 |