문제 풀이/BOJ

[C++] 백준 15666 N과 M (12)

minkylee 2024. 4. 20. 23:32

수열

수 또는 다른 대상의 순서있는 나열

  1. 나열 순서를 생각해야 하며
  2. 중복이 허용된다.

그렇다면 문제의 조건을 보자

  1. N개의 자연 수 중에서 M개를 고른 수열
  2. 같은 수를 여러 번 골라도 된다.
  3. 고른 수열은 비내림차순이여야 한다.

비내림차순 == 오름차순?

  • 비내림차순은 점점 증가하는 수열이다.

오름차순과 같아 보이겠지만 오름차순은 인접한 두 수가 같을 수도 있는지 여부를 명확하게 알려주지 않지만 비내림차순은 같을 수도 있음을 명확히 해준 것

  • 이런 경우를 위해 명시해준 것이 아닐까... 한다.

1 1 1 1 > 비내림차순이지만 과연 오름차순일까
1 2 3 4 > 비내림차순이고 오름차순

구현

  1. 들어온 수열 정렬
  2. 맨 앞칸부터 채우기
  3. 다 채우면 출력

간단하지만 수열의 중복과 순서에 대한 조건이 있기 때문에 적절하게 처리해주어야 한다.

void seq(int x, int len)
{
    if (M == len) // 길이를 다 채우면
    {
        print(); // 출력
        return;
    }
    else
    {
        int temp = 0; // 이전값을 저장할 변수
        for (int i = x; i < v.size(); i++)
        {
            if (v[i] != temp) // 이전값과 다르다면
            {
                ans[len] = v[i];
                print();
                temp = ans[len];
                seq(i, len+1); // 현재 탐색 위치부터 시작할 수 있도록 i값을 넣어준다.
            }
        }
    }
}
  • 이전 값과 같다면 수열의 중복이 발생하기 때문에 조건을 넣어줌

조건이 없다면?

  • input
  • 4 2 9 7 9 1
  • output
  • 1 0 1 1 1 1 // 중복 1 7 1 7 // 중복 1 9 1 9 7 9 7 7 7 7 7 9 7 9 9 9 9 9 // 이렇게 중복이 발생한다. 9 9

코드

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

vector<int>v;
int ans[9] = {0, };
int pre[9] = {0, };
int N, M;

void print(void)
{
    for (int i = 0; i < M; i++)
        cout << ans[i] << " ";
    cout << '\n';
}

void seq(int x, int len)
{
    if (M == len)
    {
        print();
        return;
    }
    else
    {
        int temp = 0;
        for (int i = x; i < v.size(); i++)
        {
            if (v[i] != temp)
            {
                ans[len] = v[i];
                print();
                temp = ans[len];
                seq(i, len+1);
            }
        }
    }
}

void input(void)
{
    cin >> N >> M;
    for (int i = 0; i < N; i++)
    {
        int x;
        cin >> x;
        v.push_back(x);
    }
}

void vPrint(void)
{
    for (int i = 0; i < v.size(); i++)
        cout << v[i] << " ";
    cout << '\n';
}

int main(void)
{
    input();
    sort(v.begin(), v.end());
    seq(0, 0);
}