이우의 개발일지
[백준 / C++] 15663번 N과 M (9) - (1), 백트래킹 본문
백준 15663번 N과 M (9) 문제
https://www.acmicpc.net/problem/15663
문제
N개의 자연수와 자연수 M이 주어졌을 때, 아래 조건을 만족하는 길이가 M인 수열을 모두 구하는 프로그램을 작성하시오.
- N개의 자연수 중에서 M개를 고른 수열
입력
첫째 줄에 N과 M이 주어진다. (1 ≤ M ≤ N ≤ 8)
둘째 줄에 N개의 수가 주어진다. 입력으로 주어지는 수는 10,000보다 작거나 같은 자연수이다.
출력
한 줄에 하나씩 문제의 조건을 만족하는 수열을 출력한다. 중복되는 수열을 여러 번 출력하면 안되며, 각 수열은 공백으로 구분해서 출력해야 한다.
수열은 사전 순으로 증가하는 순서로 출력해야 한다.
예제 입력 1
3 1
4 4 2
예제 출력 1
2
4
예제 입력 2
4 2
9 7 9 1
예제 출력 2
1 7
1 9
7 1
7 9
9 1
9 7
9 9
15663 N과 M 코드 문제 풀이
이 문제는 이전 N과 M 문제와는 다르게 까다로운 조건이 추가되었다.
바로, 똑같은 수가 들어갈 수 있다는 것이다. 예제 입력 이번 처럼 4가지 숫자 중 9, 7, 9, 1 같이 같은 숫자가 중복해서 들어가는데 출력할 때는 9 1, 9 7, 9 9 같이 중복되는 배열이 똑같이 나오면 안된다.
따라서, 여기서 중요한 조건이 추가되어야한다.
나는 Lastpick 변수를 이용해서 사용한 값을 기억해놓고, 다음 반복문에 들어갔을 때 그 값이 만약 중복이면 continue를 통해 다음 반복문으로 넘어가게 만들었다.
void back(int check) {
if (check == m) {
for (int i = 1; i <= m; i++) {
cout << now[i] << " ";
}
cout << '\n';
return;
}
int lastpicked = -1;
for (int i = 0; i < n; i++) {
if (issued[i]) continue;
if (lastpicked == num[i]) continue;
now[check + 1] = num[i];
issued[i] = 1;
lastpicked = num[i];
back(check + 1);
issued[i] = 0;
}
return;
}
이렇게 할 시에 예제 입력 2번을 예로 들면, 1 7 -> 1 9 -> 1 9 가 나올 타이밍에 pass를 하게 된다. 또한, 9 1 -> 9 7 -> 9 9 -> 9 1 가 나올 타이밍에 pass하게 된다. 따라서 모든 경우의 수는 출력하되 중복하는 경우는 막을 수 있게되는 조건이 추가되어 N과 M (9) 문제를 해결할 수 있다.
N과 M (9) 전체 코드
#include <iostream>
#include <algorithm>
using namespace std;
int num[9] = { 0 };
bool issued[9];
int now[9];
int n, m;
void back(int check) {
if (check == m) {
for (int i = 1; i <= m; i++) {
cout << now[i] << " ";
}
cout << '\n';
return;
}
int lastpicked = -1;
for (int i = 0; i < n; i++) {
if (issued[i]) continue;
if (lastpicked == num[i]) continue;
now[check + 1] = num[i];
issued[i] = 1;
lastpicked = num[i];
back(check + 1);
issued[i] = 0;
}
return;
}
int main() {
cin >> n >> m;
for (int i = 0; i < n; i++) {
cin >> num[i];
}
sort(num, num + n);
int now;
int past = num[0];
int n_size = n;
back(0);
return 0;
}
'Coding' 카테고리의 다른 글
[백준 / C++] 9251 LCS - 다이나믹 프로그래밍 (1) (0) | 2025.01.17 |
---|---|
[백준 / C++] 14502번 연구소 - BFS, 백트래킹 (0) | 2025.01.16 |
[백준 / C++] 15654 N 과 M (5) - 백트래킹 (0) | 2025.01.14 |
[백준 / C++] 1753 번 최단경로 구하기 - (1) , 다익스트라, 우선순위 큐 (0) | 2025.01.13 |
[백준 / C++] 11660번 구간 합 구하기 5 - (1), DP (0) | 2025.01.11 |