[ 문제 ] : https://www.acmicpc.net/problem/15650
15650번: N과 M (2)
한 줄에 하나씩 문제의 조건을 만족하는 수열을 출력한다. 중복되는 수열을 여러 번 출력하면 안되며, 각 수열은 공백으로 구분해서 출력해야 한다. 수열은 사전 순으로 증가하는 순서로 출력해
www.acmicpc.net
[ 문제 접근 ]
조합 문제고 딱히 어려울건 없었다.
방법이 너무 많아서 하나씩 다 해보느라 시간이 오래 걸렸다.
[ 방법 1 ]
#include <algorithm>
#include <string>
#include <iostream>
#include <vector>
using std::cin; using std::cout;
using std::vector;
int n, m;
int arr[9];
bool include[9];
void combination(int k,int r) {
if (r==0) {
for (int i = 0; i < n; i++) {
if (include[i]) cout << arr[i] << " ";
}
cout << '\n';
return;
}
else if (k == n) {
return;
}
include[k] = true;
combination(k + 1, r - 1);
include[k] = false;
combination(k + 1, r);
}
int main() {
std::ios::sync_with_stdio(false);
cin.tie(nullptr); cout.tie(nullptr);
cin >> n >> m;
for (int i = 0; i < n; i++) {
arr[i] = i + 1;
}
combination(0,m);
return 0;
}
include 배열 만들어서 ( 뽑을때 + 안뽑았을때 ) 를 재귀적으로 탐색.
조합을 푸는 여러가지 방법중에 가장 쉬운 방법이 아닌가 싶음.
[ 방법 2 ]
#include <algorithm>
#include <string>
#include <iostream>
#include <vector>
using std::cin; using std::cout;
using std::vector;
int n, m;
int arr[9];
vector<int> buffer;
void combination(int k,int r,int idx) {
if (r==0) {
for (auto elem : buffer) cout << elem << " ";
cout << '\n';
return;
}
else if (k == n) return;
buffer[idx] = arr[k];
combination(k+1,r-1,idx+1);
combination(k+1,r,idx);
}
int main() {
std::ios::sync_with_stdio(false);
cin.tie(nullptr); cout.tie(nullptr);
cin >> n >> m;
for (int i = 0; i < n; i++) {
arr[i] = i + 1;
}
buffer.resize(m);
combination(0,m,0);
return 0;
}
nCr = n-1Cr-1 + n-1Cr 을 이용한 풀이.
기억해야할 점은 idx (인덱스) 변수를 만들어줘야된다는 점이다.
[ 방법 3 ]
#include <algorithm>
#include <string>
#include <iostream>
#include <vector>
using std::cin; using std::cout;
using std::vector;
int n, m;
int arr[9];
vector<int> buffer;
void combination(int k,int idx) {
if (k == m) {
for (auto elem : buffer) {
cout << elem << " ";
}
cout << '\n';
return;
}
for (int i=idx; i < n; i++) {
buffer[k] = arr[i];
combination(k + 1, i + 1);
}
}
int main() {
std::ios::sync_with_stdio(false);
cin.tie(nullptr); cout.tie(nullptr);
cin >> n >> m;
for (int i = 0; i < n; i++) {
arr[i] = i + 1;
}
buffer.resize(m);
combination(0,0);
return 0;
}
중복 순열 구하는 코드와 비슷한 코드.
다음에 올 수 있는 코드를 하나 씩 크게 하면서 재귀.
[ 방법 4 ]
STL 의 prev_permutation , next_permutation을 이용한 풀이
#include <algorithm>
#include <string>
#include <iostream>
#include <vector>
using std::cin; using std::cout;
using std::vector;
int n, m;
int arr[9];
vector<bool> temp;
void combination() {
do {
for (int i = 0; i < n; i++) {
if (temp[i]) cout << arr[i] << " ";
}
cout << '\n';
} while (std::prev_permutation(temp.begin(),temp.end()));
}
int main() {
std::ios::sync_with_stdio(false);
cin.tie(nullptr); cout.tie(nullptr);
cin >> n >> m;
for (int i = 0; i < n; i++) {
arr[i] = i + 1;
}
temp.resize(n);
for (int i = 0; i < m; i++) {
temp[i] = true;
}
combination();
return 0;
}
#include <algorithm>
#include <string>
#include <iostream>
#include <vector>
using std::cin; using std::cout;
using std::vector;
int n, m;
int arr[9];
vector<bool> temp;
void combination() {
do {
for (int i = 0; i < n; i++) {
if (!temp[i]) cout << arr[i] << " ";
}
cout << '\n';
} while (std::next_permutation(temp.begin(),temp.end()));
}
int main() {
std::ios::sync_with_stdio(false);
cin.tie(nullptr); cout.tie(nullptr);
cin >> n >> m;
for (int i = 0; i < n; i++) {
arr[i] = i + 1;
}
temp.resize(n);
for (int i = n-m; i < n; i++) {
temp[i] = true;
}
combination();
return 0;
}
[ 다른 사람 풀이 ]
ref :: https://m.blog.naver.com/ndb796/221240353788
ref ::
'PS > BaekJoon' 카테고리의 다른 글
[15652] N과 M(4) - 중복 조합 ★★☆☆ / 복습 ○ (0) | 2021.12.11 |
---|---|
[15651] N과 M(3) - 중복 순열 ★★☆☆ / 복습 ○ (0) | 2021.12.11 |
[1182] 부분수열의 합 - 백트랙킹 ★★☆☆ / 복습 ○ (0) | 2021.12.10 |
[9663] N-Queen - 백트랙킹 ★★☆☆ / 복습 ○ (0) | 2021.12.10 |
[2252] 쿼드트리 - 재귀/분할정복 ★★☆☆ / 복습 ○ (0) | 2021.12.02 |