[C] 백준 15657번 N과 M (8)

김진웅·2024년 1월 2일
0

baekjoon-study

목록 보기
47/59
post-thumbnail

링크
https://www.acmicpc.net/problem/15657




문제


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

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

입력


첫째 줄에 N과 M이 주어진다. (1 ≤ M ≤ N ≤ 8)

둘째 줄에 N개의 수가 주어진다. 입력으로 주어지는 수는 10,000보다 작거나 같은 자연수이다.


출력


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

수열은 사전 순으로 증가하는 순서로 출력해야 한다.


예제 입력 1


3 1
4 5 2

예제 출력 1


2
4
5

예제 입력 2


4 2
9 8 7 1

에제 출력 2


1 1
1 7
1 8
1 9
7 7
7 8
7 9
8 8
8 9
9 9

예제 입력 3


4 4
1231 1232 1233 1234

예제 출력 3


1231 1231 1231 1231
1231 1231 1231 1232
1231 1231 1231 1233
1231 1231 1231 1234
1231 1231 1232 1232
1231 1231 1232 1233
1231 1231 1232 1234
1231 1231 1233 1233
1231 1231 1233 1234
1231 1231 1234 1234
1231 1232 1232 1232
1231 1232 1232 1233
1231 1232 1232 1234
1231 1232 1233 1233
1231 1232 1233 1234
1231 1232 1234 1234
1231 1233 1233 1233
1231 1233 1233 1234
1231 1233 1234 1234
1231 1234 1234 1234
1232 1232 1232 1232
1232 1232 1232 1233
1232 1232 1232 1234
1232 1232 1233 1233
1232 1232 1233 1234
1232 1232 1234 1234
1232 1233 1233 1233
1232 1233 1233 1234
1232 1233 1234 1234
1232 1234 1234 1234
1233 1233 1233 1233
1233 1233 1233 1234
1233 1233 1234 1234
1233 1234 1234 1234
1234 1234 1234 1234




아이디어 스케치


이 문제에서 구해야할 수열의 조건을 살펴보면

N개의 자연수 중에서 M개를 고르고,
같은 수를 여러 번 골라도 되고,
고른 수열은 비내림차순이어야 한다.
수열은 사전 순으로 증가하는 순서로 출력해야 한다.

위 조건들을 만족하는 수열을 구하면 된다.

문제의 로직

  1. N과 M을 입력 받은 후 N개의 숫자를 입력받아 list 배열에 저장

  2. 수열을 사전 순으로 증가하는 순서로 출력하기 위해 퀵 정렬을 이용하여 오름차순 정렬을 수행

  3. 현재 수열의 이전 자릿수보다 현재 선택한 숫자가 같거나 큰 경우에만 수열을 생성

  4. 현재 수열의 길이가 M과 같아진 경우에 결과를 출력




전체 코드


#include <stdio.h>
#include <stdlib.h>

int N, M;
int result[1000];	// 완성된 하나의 수열을 저장하는 배열
int list[8];		// 입력으로 주어지는 수를 저장하는 배열

// 퀵정렬을 위한 compare 함수(오름차순 정렬)
int compare(const void* f, const void* s)
{
	if (*(int*)f > *(int*)s)
		return 1;
	else if (*(int*)f < *(int*)s)
		return -1;
	else
		return 0;
}

// 조건에 맞는 순열을 찾아 출력하는 함수
void Sequence(int depth, int cut)
{
	int i;

	if (depth == M)		// 조건을 만족하는 길이가 M인 수열을 구한 경우
	{
		for (i = 0; i < M; i++) {
			printf("%d ", result[i]);	// 결과 출력
		}

		printf("\n");
	}
	else
	{
		for (i = 0; i < N; i++)
		{
			// 이전 자릿수보다 큰 숫자만 사용
			if (cut <= list[i]) {
				result[depth] = list[i];			// 현재 자리수에 list[i]값을 저장
				Sequence(depth + 1, list[i]);		// 다음 자리수를 탐색
			}
		}
	}
}
int main(void)
{
	scanf("%d %d", &N, &M);
	for (int i = 0; i < N; i++)
		scanf("%d", &list[i]);

	//수열을 사전 순으로 증가하는 순서로 출력하기 위해 오름차순 정렬 수행
	qsort(list, N, sizeof(int), compare);


	Sequence(0,0);	// depth는 0부터 시작
	return 0;

}




제출 결과


profile
IT Velog

0개의 댓글