www.acmicpc.net/problem/15666

 

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

+ Recent posts