(C++) 백준 15652번 - N과 M(4)

코딩너구리·2025년 12월 10일

코딩 문제 풀이

목록 보기
121/266

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

문제

> 자연수 N과 M이 주어졌을 때, 아래 조건을 만족하는 길이가 M인 수열을 모두 구하는 프로그램을 작성하시오.

> 1부터 N까지 자연수 중에서 M개를 고른 수열
> 같은 수를 여러 번 골라도 된다.
> 고른 수열은 비내림차순이어야 한다.
> 길이가 K인 수열 A가 A1 ≤ A2 ≤ ... ≤ AK-1 ≤ AK를 만족하면, 비내림차순이라고 한다.

접근

재귀를 사용하여 각 자리수마다 가능한 수를 넣어 주고 수열의 길이가 입력으로 받은 M에 만족한다면 저장된 수열을 출력해주고 가능한 다음 수열을 탐색한다.
문제에서 비내림차순이라고 했기 때문에 오름차순이고, 중복이 가능하다고했으니 재귀로 다음 수를 넘길 때 i를 넘겨주면 같은수에 대한 수열도 탐색하기 때문에 111, 222같은 조합이 가능하다.

문제해결

> 재귀의 탈출조건이자 수열의 출력조건을 입력받은 수열의 길이 M이 되면 rst에 저장된 수열을 출력하도록한다.
> 재귀에선 각 자리별로 함수의 인자로 받은 start값으로 탐색을 시작하며 size는 현재 탐색중이 수열의 자릿수가 된다. 
> 흐름을 따라가보면 처음에 1,0으로 main에서 들어간다.
> 함수에서 조건에 걸리지 않고 반복문으로 들어가 1부터 입력받은 N까지 반복문을 도는데
각 반복문마다 재귀로 들어간다.
> 두번째 자리도 start가 1이 들어왔으므로 1부터 반복문이 돌며 재귀로 1,2가 들어간다.
1,2에 대해 마지막 세번째 자리도 1로 되고 1,3이 넘어갔을 때 재귀의 조건에 걸려 1,1,1이 출력된다.
>이제 return으로 다시 세번째 자리 탐색으로 돌아가 반복문이 1은 봤으므로 i++에 의해 2로 올라가 2,3으로 재귀가 넘어간다.
> 조건에 걸려 1,1,2가 출력된다.
> 이 흐름으로 중복이 가능한 비내림차순 구조의 수열이 나온다.

코드

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

int N, M;
vector<int> rst;
void Num(int start, int size)
{
	if (size == M)
	{
		for (auto a : rst)
		{
			cout << a << " ";
		}
		cout << '\n';
		return;
	}
	for (int i = start; i <= N; i++)
	{
		rst[size] = i;
		Num(i, size + 1);
	}
}
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);

	cin >> N >> M;
	rst.resize(M);

	Num(1, 0);
}

후기

문제가 거창해서 잘 읽어보니 비내림차순 -> 같은수로 이루어진 수열도 가능한 오름차순 이었다.

0개의 댓글