N과 m (2)
[Silver III] N과 M (2) - 15650
성능 요약
메모리: 1116 KB, 시간: 0 ms
분류
백트래킹
제출 일자
2023년 12월 31일 20:46:53
문제 설명
자연수 N과 M이 주어졌을 때, 아래 조건을 만족하는 길이가 M인 수열을 모두 구하는 프로그램을 작성하시오.
- 1부터 N까지 자연수 중에서 중복 없이 M개를 고른 수열
- 고른 수열은 오름차순이어야 한다.
입력
첫째 줄에 자연수 N과 M이 주어진다. (1 ≤ M ≤ N ≤ 8)
출력
한 줄에 하나씩 문제의 조건을 만족하는 수열을 출력한다. 중복되는 수열을 여러 번 출력하면 안되며, 각 수열은 공백으로 구분해서 출력해야 한다.
수열은 사전 순으로 증가하는 순서로 출력해야 한다.
TIL
- 가지치기의 조건만 잘 설정해두면 무리없이 구현했다.
BackTracing
- 확장
- 가지치기
- 끝까지 간뒤에 다시 올라오기 (이때 원상태로 복원시키면서)
Feedback
- M과 N 시리즈의 1번 문제를 조금 응용하면 쉽게 풀 수 있었다.
가지치기만 신경써서 구현하면 될 듯
내 코드
#include <stdio.h>
#include <stdbool.h>
#define SIZE 9
void combination(int arr[],bool isVisted[],int N,int M,int depth);
int main(){
int N,M;
scanf("%d %d",&N,&M);
int arr[SIZE]={0};
bool isVisted[SIZE]={0};
combination(arr,isVisted,N,M,0);
return 0;
}
//arr[depth] 추가하는 함수
void combination(int arr[],bool isVisted[],int N,int M,int depth){
//종료 조건 : depth가 M이면 arr는 다 찼음. 출력
if(depth==M){
for(int i=0;i<M;i++){
printf("%d ",arr[i]);
}
printf("\n");
return;
}
//방문
//확장
for(size_t i=1;i<=N;i++){
//가지치기
bool flag=true; // 숫자 i를 탐색하는게 맞는 것인가?
for(size_t j=i;j<=N;j++){
if(isVisted[j]) flag=false;
}
if(flag){
isVisted[i]=true;
arr[depth]=i;
//재귀
combination(arr,isVisted,N,M,depth+1);
//올라오면서 원상태로 되돌리기
isVisted[i]=false;
}
}
}
Leave a comment